在 Vue2 中,主页面给子页面传递数据主要通过 props 实现。以下是几种常见场景和实现方式:
1. 父子组件通信 - 使用 Props
基本用法
父组件 (Parent.vue)
<template>
<div>
<ChildComponent
:message="parentMessage"
:user="userData"
:count="counter"
@update-data="handleUpdate"
/>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
data() {
return {
parentMessage: 'Hello from parent!',
userData: {
name: 'John',
age: 25
},
counter: 0
}
},
methods: {
handleUpdate(newData) {
this.counter = newData
}
}
}
</script>
子组件 (ChildComponent.vue)
<template>
<div>
<h3>子组件</h3>
<p>消息: {{ message }}</p>
<p>用户名: {{ user.name }}</p>
<p>年龄: {{ user.age }}</p>
<p>计数: {{ count }}</p>
<button @click="updateCount">更新计数</button>
</div>
</template>
<script>
export default {
// 定义 props
props: {
// 基础类型检测
message: {
type: String,
required: true
},
// 对象类型
user: {
type: Object,
default: () => ({})
},
// 数字类型
count: {
type: Number,
default: 0
}
},
methods: {
updateCount() {
// 通过事件向父组件传递数据
this.$emit('update-data', this.count + 1)
}
}
}
</script>
2. Props 的多种定义方式
<script>
export default {
props: {
// 基础类型检查
propA: Number,
// 多种类型
propB: [String, Number],
// 必填且为字符串
propC: {
type: String,
required: true
},
// 默认值
propD: {
type: Number,
default: 100
},
// 对象/数组的默认值
propE: {
type: Object,
default: () => ({
message: 'hello'
})
},
// 自定义验证函数
propF: {
validator: function(value) {
return ['success', 'warning', 'danger'].includes(value)
}
}
}
}
</script>
3. 动态 Props
父组件
<template>
<div>
<input v-model="dynamicMessage" placeholder="输入消息">
<ChildComponent :message="dynamicMessage" />
<!-- 传递计算属性 -->
<ChildComponent :computed-message="computedMessage" />
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
data() {
return {
dynamicMessage: ''
}
},
computed: {
computedMessage() {
return this.dynamicMessage.toUpperCase()
}
}
}
</script>
4. 使用 $attrs 传递属性
父组件
<template>
<ChildComponent
title="页面标题"
description="页面描述"
class="custom-class"
data-custom="custom-data"
/>
</template>
子组件
<template>
<div v-bind="$attrs">
<!-- $attrs 包含所有非 props 的属性 -->
<p>标题: {{ $attrs.title }}</p>
<p>描述: {{ $attrs.description }}</p>
</div>
</template>
<script>
export default {
inheritAttrs: false, // 禁止默认的属性继承
created() {
console.log(this.$attrs) // 输出所有传入的属性
}
}
</script>
5. 通过 parent 和 refs
父组件
<template>
<div>
<ChildComponent ref="childRef" />
<button @click="callChildMethod">调用子组件方法</button>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
methods: {
callChildMethod() {
// 通过 ref 访问子组件实例
this.$refs.childRef.childMethod('来自父组件的数据')
}
}
}
</script>
子组件
<script>
export default {
methods: {
childMethod(data) {
console.log('接收到数据:', data)
// 也可以通过 $parent 访问父组件
console.log('父组件数据:', this.$parent.someData)
}
}
}
</script>
-
优先使用 props 进行父子组件通信
-
使用事件 让子组件向父组件传递数据
-
避免直接修改 props,应该通过事件通知父组件修改