父组件通过
props
传值给子组件,当父组件传值发生了变化,我们期望子组件数据相应进行变化。方法较多,我们一一介绍。
先写一个简易的父组件
// 父组件template内容
<button @click="addData">addDataButton</button>
// 引用的子组件内容
<data-list-item :dataList="dataList"></data-list-item>
// 父组件data中定义内容
dataList: [],
// 父组件methods内容
addData() {
this.dataList.push({
name: this.dataList.length,
})
}
再写一个简易的子组件
// 子组件template内容
<ul>
<li></li>
</ul>
// 子组件props中内容
props: ['dataList'],
props
直接使用父组件传递的
props
变量
// 子组件template内容
<ul>
<li v-for="(list, index) in dataList" :key="index">{{ list.name }}</li>
</ul>
我们可以看出来随着父组件数据的变化,props传递的字段dataList值动态变化。但这样存在一个弊端,就是在子组件中无法根据各类条件进一步处理传递的数据,所以我们更倾向于下一种。
data
将
props
中的值赋给
data
中定义的变量
// 子组件template内容
<ul>
<li v-for="(list, index) in childDataList" :key="index">{{ list.name }}</li>
</ul>
// 子组件data中定义内容
childDataList: this.dataList,
在vue调试工具中我们可以轻易看到,当我们点击按钮,props中的值进行相应变化,同时data中定义的变量值也同步变化。
computed
如果父组件传递的值,在给定的初始条件即可完成数据的处理,那我们可以使用
computed
// 子组件template内容
<ul>
<li v-for="(list, index) in childDataList" :key="index">{{ list.name }}</li>
</ul>
// 子组件computed中定义内容
childDataList() {
return this.dataList
},
在vue调试工具中我们可以轻易看到,当我们点击按钮,props中的值进行相应变化,同时computed中定义的变量childDataList也同步变化。
watch
采用
watch
监听父组件传值也是常用的方法。
watch可以直接监听变化的传值类型为基本数据类型,引用数据类型可以监听Array,但是对引用数据类型中 instanceOf 为 Object监听则不是很理想,需要使用watch中的深度监听。
普通监听
// 子组件template内容
<ul>
<li v-for="(list, index) in childDataList" :key="index">{{ list.name }}</li>
</ul>
// 子组件data中定义内容
childDataList: [],
// 子组件watch中定义的内容
dataList(val) {
console.log('dataList change', val)
this.childDataList = val
},
可以看到随着父组件按钮的点击,子组件对父组件的传值监听会执行,同时改变子组件data中定义的childDataList值。这种方式的问题是,如果一开始父组件即传值过来,而watch是监听到变化才执行,则导致子组件无初始值。可以采用下面深度监听的写法,开启
immediate
为
true
。
深度监听
修改下之前的父组件和子组件内容
// 父组件template内容修改
<button @click="changeData">changeDataButton</button>
<data-list-item :dataObj="dataObj"></data-list-item>
// 父组件data内容修改
dataObj: {
name: 'caoyuan',
age: 24,
sex: 'man',
},
// 父组件methods内容修改
changeData() {
this.dataObj.name = this.dataObj.name + Math.random()
},
// 子组件template内容修改
<div>
{{ personalInfo.name }}
</div>
// 子组件data内容修改
personalInfo: {},
// 子组件props修改
props: ['dataObj'],
// 子组件watch修改
watch: {
dataObj: {
handler(val) {
console.log('dataObj deep change', val)
this.personalInfo = val
},
deep: true, // 深度监听
immediate: true, // 初次监听即执行
},
},
通过上面的方式,即可解决watch监听带来的一些问题
优化watch监听
若是只对object中特定字段进行监听,则可以采用下面方式
watch: {
'dataObj.name': {
handler(val) {
console.log('dataObj.name change', val)
this.personalInfo = this.dataObj
},
immediate: true, // 初次监听即执行
},
},
这种方式消除深度监听对性能的消耗