vue子组件监听父组件数据变化并作出改变(亲测有效)

Posted 进击的yuan人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue子组件监听父组件数据变化并作出改变(亲测有效)相关的知识,希望对你有一定的参考价值。

vue子组件监听父组件数据变化并作出改变(亲测有效)

1. 问题

1.1 封装组件时经常会遇到子组件需要根据父组件数据变化并执行对应的操作逻辑
1.2 监听方法中加了deep、immediate 等参数监听数组/对象还是没有生效
1.3 类型table组件需要根据父组件数据变化对表格数据进行更新
1.4 根据数据动态渲染组件需实时监听父组件变化
1.5 使用$refs 有些时候很难找到嵌套组件的ref

2. 思路

2.1 本文章主要的思路就是 provide / inject

2.2 创建父组件时,无论有多少层级的子组件都可以进行数据的相互依赖
2.3 那么在组件可以利用这个依赖对父组件数据进行监听

3. 解决方法

3.1 首先在父组件定义 provide,代码如下
//父组件提供参数给子组件(响应式时需设置为对象)
provide()
  return 
    superParams:this
  
,
data() //定义几个参数
	return 
		test:
          testLevel1:
            testLevel2:''
          
        ,
        testList:[]
	

3.2 子组件添加 inject,代码如下
// 子组件:childrenComponent1
inject: ['superParams'],
watch: //监听数据变化
  'superParams.test':
      immediate:true, // 将立即以表达式的当前值触发回调
      handler:function (val,oldVal) 
          console.log("监听test对象");
          console.log(val,oldVal);
      ,
      deep:true,
  ,
  'superParams.test.testLevel1':
      immediate:true, // 将立即以表达式的当前值触发回调
      handler:function (val,oldVal) 
          console.log("监听testLevel1属性");
          console.log(val,oldVal);
      ,
      deep:true,
  ,
  'superParams.test.testLevel1.testLevel2':
      immediate:true, // 将立即以表达式的当前值触发回调
      handler:function (val,oldVal) 
          console.log("监听testLevel1属性");
          console.log(val,oldVal);
      ,
      deep:true,
  ,
  'superParams.testList':
      immediate:true, // 将立即以表达式的当前值触发回调
      handler:function (val,oldVal) 
          console.log("监听testList数组");
          console.log(val,oldVal);
      ,
      deep:true,
  

3.3 另外一个子组件触发父组件数据变化(同/不同层级都可以触发)
// 子组件:childrenComponent2
inject: ['superParams'],
mounted()
   this.superParams.test.testLevel1.testLevel2 = 'testLevel22';
   this.superParams.testList.push(test:'test')

举例一(子组件按顺序展示):先显示childrenComponent2 ,再到childrenComponent1,(下图的数据在childrenComponent1展示后输出)结果如图所示

举例二(子组件都展示, 在父组件或其他地方触发数据更新)

在父组件添加一个按钮点击触发方法代码如下

updateText()
  console.log("Text数据更新");
  this.test.testLevel1.testLevel2 = 'testLevel22';
  this.testList.push(test:'test')

结果如下图所示

注意

  1. 当前组件监听方法数据作出了改变,但组件却没有更新,这时需在组件本身找更新原因
  2. 组件显示时会对监听方法进行初始化
  3. 对于对象存在多层的监听问题,可监听整个对象
  4. 对于数组会不会存在漏监听的情况,经测试调用数组的pop、push、shift、unshift、splice、sort、reverse等方法时是可以监听到数组的变化
  5. immediate、deep 要了解

补充

针对注意点1,以el-input-number(element ui)组件为例

<el-input-number v-model="item.max" @change="handleChange" :min="0" :key="Math.random()" :max="superParams.max"></el-input-number>

在没有加上 :key=“Math.random()” 前组件并没有随着父组件数据(superParams.max)变化

加上后可根据父组件数据动态改变

父组件改变参数值代码如下图所示

'formData.isTrue':function (val,oldVal) 
 if(val)
   this.max = 100;
 else 
   this.max = 50;
 
,

并不是所有组件都能用 :key=“Math.random()” ,某些组件使用后会出现卡顿或者无法输入值

vue父组件数据变化,子组件不变的情况解决

参考技术A 在父组件中的数据发生变化时,传给子组件,子组件未发生变化。
解决方法:看子组件是否能监听到子组件的变化,然后mounted赋值给子组件的绑定的变量中。

如果有什么问题希望大家多交流。

以上是关于vue子组件监听父组件数据变化并作出改变(亲测有效)的主要内容,如果未能解决你的问题,请参考以下文章

【技术】Vue 父组件如何监听子组件的生命周期

vue---父组件监听子组件并获取子组件的值(子组件多个值)

vue 子组件监听父组件的值并操作

初识vue 2.0(13):子组件使用watch监听父组件变化

vue3实现父组件向子组件传值并监听props改变触发事件

父组件传异步数据给子组件问题