<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<!-- 引入 vue 入口文件 -->
<script type="module" src="./main.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
index.html
main.js
App.vue
global.css
package.json
Son.vue
现在支持上传本地图片了!
index.html
main.js
import { createApp } from 'vue'
import './global.css'
import App from './App.vue'
createApp(App).mount('#app')
编辑器加载中
App.vue
<script setup>
import { ref } from 'vue';
import SonComponent from './Son.vue';
// 父组件的数据
const parentMessage = ref('来自父组件的消息');
const parentCounter = ref(0);
// 父组件的方法
const incrementCounter = () => {
parentCounter.value++;
};
const resetCounter = () => {
parentCounter.value = 0;
};
// 处理由子组件触发的事件
const handleUpdateMessage = (newMessage) => {
console.log('父组件收到更新消息请求:', newMessage);
parentMessage.value = newMessage;
};
const handleResetRequest = () => {
console.log('父组件收到重置计数器请求');
resetCounter();
};
</script>
<!-- App.vue -->
<template>
<div class="app-container">
<h1>Vue 3 父子组件传值演示</h1>
<p><strong>父组件(App.vue)的数据:</strong></p>
<ul>
<li>消息: {{ parentMessage }}</li>
<li>计数器: {{ parentCounter }}</li>
</ul>
<div class="input-section">
<label for="newMessage">更新父组件消息: </label>
<input id="newMessage" v-model="parentMessage" placeholder="输入新消息" />
</div>
<div class="button-section">
<button @click="incrementCounter">增加父组件计数器</button>
<button @click="resetCounter">重置父组件计数器</button>
</div>
<hr />
<!-- 传递数据给子组件 -->
<!-- 使用 v-bind (或简写 :) 传递 props -->
<!-- 使用 v-on (或简写 @) 监听子组件触发的事件 -->
<SonComponent
:message="parentMessage"
:counter="parentCounter"
@update-message="handleUpdateMessage"
@reset-request="handleResetRequest"
/>
</div>
</template>
<style scoped>
.app-container {
max-width: 800px;
margin: 20px auto;
padding: 20px;
border: 1px solid #ccc;
border-radius: 8px;
font-family: Avenir, Helvetica, Arial, sans-serif;
color: #2c3e50;
}
.input-section {
margin: 15px 0;
}
.input-section input {
padding: 5px;
margin-left: 10px;
border: 1px solid #ddd;
border-radius: 4px;
}
.button-section button {
margin-right: 10px;
padding: 8px 16px;
background-color: #42b983;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.button-section button:hover {
background-color: #359c6d;
}
hr {
margin: 20px 0;
border: 0;
border-top: 1px solid #eee;
}
</style>
编辑器加载中
global.css
body {
background-color: #fefefe;
}
编辑器加载中
package.json
注意:新添加的依赖包首次加载可能会报错,稍后再次刷新即可
{
"dependencies": {
"vue": "3.5.15"
}
}
编辑器加载中
Son.vue
<script setup>
import { ref, watch } from 'vue';
// 定义接收的 props
const props = defineProps({
message: {
type: String,
required: true
},
counter: {
type: Number,
required: true
}
});
// 子组件内部状态,用于输入框
const localMessage = ref(props.message);
// 当 props.message 变化时,更新本地的 localMessage
// 这样可以保持输入框与父组件数据的同步(如果需要的话)
watch(() => props.message, (newVal) => {
localMessage.value = newVal;
});
// 定义要触发的事件
const emit = defineEmits(['update-message', 'reset-request']);
// 子组件的方法
const sendUpdateMessage = () => {
console.log('子组件触发 update-message 事件');
// 使用 emit 触发事件,并传递数据
emit('update-message', localMessage.value);
};
const requestReset = () => {
console.log('子组件触发 reset-request 事件');
// 触发事件,不传递数据
emit('reset-request');
};
</script>
<!-- Son.vue -->
<template>
<div class="son-container">
<h2>子组件 (Son.vue)</h2>
<p><strong>从父组件接收到的 Props:</strong></p>
<ul>
<li>消息 (message): {{ message }}</li>
<li>计数器 (counter): {{ counter }}</li>
</ul>
<div class="input-section">
<label for="childMessage">子组件更新消息: </label>
<input id="childMessage" v-model="localMessage" placeholder="输入要发送给父组件的消息" />
<button @click="sendUpdateMessage">发送消息给父组件</button>
</div>
<div class="button-section">
<button @click="requestReset">请求父组件重置计数器</button>
</div>
</div>
</template>
<style scoped>
.son-container {
padding: 20px;
border: 1px dashed #42b983;
border-radius: 8px;
background-color: #f9f9f9;
}
.input-section {
margin: 15px 0;
}
.input-section input {
padding: 5px;
margin: 0 10px;
border: 1px solid #ddd;
border-radius: 4px;
}
.input-section button, .button-section button {
padding: 8px 16px;
background-color: #34495e;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.input-section button:hover, .button-section button:hover {
background-color: #2c3e50;
}
</style>
编辑器加载中
预览页面