vue子组件监听父组件传值

Vue 专栏收录该内容
15 篇文章 1 订阅


父组件通过 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是监听到变化才执行,则导致子组件无初始值。可以采用下面深度监听的写法,开启immediatetrue

深度监听

修改下之前的父组件和子组件内容

// 父组件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, // 初次监听即执行  
  },
},

这种方式消除深度监听对性能的消耗

  • 7
    点赞
  • 2
    评论
  • 16
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值