vue父子组件之间双向数据绑定的三种方式(vue2/vue3)
·
在做项目的过程中,经常遇到父子组件通信的问题,现在对3种通信方式总结一下:
一、prop向下传递,emit向上传递
初始版本
父组件通过prop将数据传递给子组件,子组件通过emit事件将子组件数据传递给父组件
//父组件
<template>
<div>
<child :value='value' @getChildData='getChildData'></child>
来自子组件的数据:<span>{{value}}</span>
<div/>
</template>
<script>
data() {
return {
value: '父组件的数据'
}
},
methods:{
getChildData(v){
this.value = v
}
}
</script>
//子组件child
<template>
<input v-model='childValue' @input='childInputChange'></input>
</template>
<script>
props:{
value:{
type:String,//在props接受父组件传递数据
default:''
}
},
data(){
return {
childValue:this.value
}
},
watch:{
value(){
this.childValue = this.value //监听父组件的数据,同步更新子组件数据
}
},
methods:{
childInputChange(){
this.$emit('getChildData',this.childValue) // 通过emit触发getChildData,将子组件数据传递给父组件
}
</script>
二、v2.2.0+ 新增 v-model 通过v-model属性实现
//父组件
<template>
<div>
<child v-model='value'></child>
// 等价于 默认给子组件传递参数value,子组件更新函数名update:value
<child :value='value' @update:value='val=>{ value = val }'></child>
// 在子组件中可以通过model配置
//接受数据的名字fatherValue和触发事件的方法childValueChange
<child :fatherValue='value' @childValueChange = "val=>{ value = val }"></child>
父子组件同步的数据:<span>{{value}}</span>
<div/>
</template>
<script>
data() {
return {
value: '父组件的数据'
}
}
</script>
//子组件child
<template>
<input type="text" v-model="childValue" @input="childInputChange"/>
</template>
<script>
export default {
name: "child",
model: { // 定义model
prop: 'fatherValue', // 父组件v-model绑定的值传递给props中的fatherValue
event: 'childValueChange'
// 通过emit触发childValueChange将内部值传递给父组件v-model绑定的值
},
props: {
fatherValue: String // 接受父组件传递的值
},
data(){
return {
childValue: this.fatherValue// 关联值
}
},
methods: {
childInputChange(){
// 通过$emit触发childValueChange(model内定义)事件,将内部值传递给给父组件
this.$emit('childValueChange', this.childValue)
}
}
}
</script>
vue3允许写多个v-model,vue2不允许写多个v-model
//父组件
<template>
<div>
<child v-model:value1='dValue1' v-model:value2='dValue2'></child>
// 等价于 默认给子组件传递两个值value1、value2
// 子组件更新函数update:value1将接受到的参数赋值给dValue1
// 子组件更新函数update:value2将接受到的参数赋值给dValue2
<child :value1='dValue1' @update:value1='val=>{ dValue1= val }'
:value1='dValue2' @update:value1='val=>{ dValue2= val }'
></child>
<div/>
</template>
<script>
data() {
return {
dValue1: '父组件的数据1',
dValue2: '父组件的数据2'
}
}
</script>
三、sync修饰符(v2.3.0+ 新增)
// 父组件
<template>
<div>
我是父子组件之间同步的数据{{data}}
<child :data.sync='data'></child>
</div>
</template>
<script>
data(){
return {
data:'我是来自父组件的数据'
}
}
</script>
//子组件
<template>
<div>
<input type="text" v-model="childData" @input="childDataChange">
</div>
</template>
<script>
props:{
data:{
default:'',
type:String
}
},
data(){
return {
childData:this.data //关联父组件的值
}
},
watch:{
data(){
this.childData = this.data
}
},
methods:{
childDataChange(v){
this.$emit('update:data',v) // 触发update:data将子组件值传递给父组件
}
}
</script>
vue3取消了.sync这种语法,使用v-model:title 语法代替
// 父组件
<template>
<div>
我是父子组件之间同步的数据{{data}}
// 父组件传递给子组件title属性(默认使用value)
// 通过update:title(默认使用update:value) 方法将子组件传递的值赋值给data
<child v-model:title = data></child>
</div>
</template>
<script>
data(){
return {
data:'我是来自父组件的数据'
}
}
</script>
//子组件
<template>
<div>
<button @input="childDataChange">{{title}}</button>
</div>
</template>
<script>
props:{
title:{
default:'',
type:String
}
},
methods:{
childDataChange(v){
this.$emit('update:title',v) // 触发update:data将子组件值传递给父组件
}
}
</script>
更多推荐
已为社区贡献3条内容
所有评论(0)