vue中props传值无法被watch监听的解决办法

18,558 阅读1分钟

1. 普通组件的watch监听props传参

首先在html中载入子组件

over-view(v-if="false" :getTime="startTime" @value-begin="getBegin" @value-updated="getUpdate")

然后在js中的watch中增加监听事件

watch: {
    getTime(newValue, oldValue) {
       console.log('props', newValue)
    }
},

这个时候是完全没有问题的

2.动态组件component中watch监听props

html中加入component组件

keep-alive(v-for="(item, index) in compArr" :key="index")
  component(:is="currentTabComponent"
            :propsTime="startTime"
            @value-begin="getBegin"
            @value-updated="getUpdate")

js中监听

watch: {
    propsTime: {
      handler (newValue, oldValue) {
      
        console.log('props', newValue)
        this.getOverviewData()
      },
      // 这里增加了一个immediate属性,说明监听到props传参后立即先去执行handler方法
      immediate: true,
    },
  },

3. immediate属性

我们看下官网的介绍,watch有好几种方来监听某个属性

如果通过动态组件来切换组件里面的watch是不会监听props第一次传值的。要等到propsTime值改变时才执行监听计算。
那我们想要一开始就让他最初绑定的时候就执行,这个时候就要加入immediate属性

4. deep属性

watch 里面还有一个属性 deep,默认值是 false,代表是否深度监听

在data中定义一个多层对象rankingList,这个时候我要监听rankingList中data的变化


export default {
  name:'over-view',
  data () {
    return {
      rankingList: {
        data: 1
      },
    };
  },
  props:[],
  watch: {
    rankingList: {
      handler (newValue, oldValue) {
      
        console.log('props', newValue)
      },
      immediate:true,
      deep: true
    }
  },
  computed: {},
  methods: {},
  mounted: {}
};

但是这样性能开销就会很大,假如一个对象里面有多层嵌套,里面任何一个属性变换都会触发这个监听器里的 handler。

这个时我们可以优化下,可以是使用字符串形式监听。

watch: {
  'rankingList.data': {
    handler(newValue, oldValue) {
      console.log('props', oldValue);
    },
    immediate: true,
    // deep: true
  }
} 

这样Vue.js才会一层一层解析下去,直到遇到属性data,然后才给data设置监听函数。