Vue中可以使用监听器监听属性的变化,并根据属性变化作出响应。但一旦涉及到复杂数据的监听(如Object,但数组一般不需要,因为Vue针对数组做了特殊处理)时就比较复杂了,本文解释了使用watch监听属性变化的方法,包括复杂数据。

基本用法

Vue watch最重要的使用场景是根据某属性的变化执行某些业务逻辑:

<template><input type="number" v-model.number="counter" />
</template><script>
export default {name: "Counter",data: function() {return {counter: 0,};},watch: {counter: function(newV, oldV) {console.log('counter change to %d from %d', newV, oldV);},}
};
</script>

watch的基本用法很简单:针对需要监听的属性定义个同名的函数即可,函数的第一个参数为变化后的值,第二个参数为变化前的值。

监听object

首先我们回顾一个JavaScript中的概念:复杂数据变量。“复杂”的原因在于变量只是一个引用,和C++中的指针类似,其保存的不是真实的数据,而是数据的地址。比如对于一个object变量来说,添加属性、删除属性、修改属性的值都不会改变这个地址,这也可以说这个object变量没有变化。不管所用的框架如何,基本定理肯定是生效的,所以Vue中监听object也是一难题,特别是嵌套数据的监听。

这里的变化指的是地址的变化,能够触发变化最简单的方式就是重新赋值。

<template><div><label>up trigger {{ counter.up }} times</label><button @click="onTrigger('up')">Trigger Up</button><br><label>down trigger {{ counter.down }} times</label><button @click="onTrigger('down')">Trigger down</button></div>
</template><script>
export default {name: "Counter",data: function() {return {counter: {up: 0,down: 0,},};},methods: {onTrigger: function(type) {this.counter[type] += 1;}},watch: {counter: function(newV, oldV) {// 不会被触发console.log('counter change to %o from %o', newV, oldV);},}
};
</script>

针对counter的监听不会被触发,因为this.counter[type] += 1;并不会使this.counter变化(地址没变)。那如果想要监听到这个变化应该怎么办呢?一般来说有两种方式:

使用deep参数

watch: {counter: {handler: function(newV, oldV) {console.log('counter change to %o from %o', newV, oldV);},deep: true,}
}

使用deep需要使用watch的完整形式:handler是监听回调函数,deep: true指定了不仅仅监听counter的变化,也监听其内部属性的变化,所以当counter.upcounter.down变化时才能出发handler回调。

重新赋值

methods: {onTrigger: function(type) {// 重新赋值触发变化this.counter = {...this.counter,[type]: this.counter[type] + 1,};}
},
watch: {counter: function(newV, oldV) {// 不会被触发console.log('counter change to %o from %o', newV, oldV);},
}

那两种方式优劣如何呢?使用deep参数会为数据每一层都添加监听,当层级较深时比较耗费性能,而且Vue不能监听到属性的添加或删除。所以一般来说使用重新赋值的方式是较优的方案,但如果只是想监听内部嵌套数据的话,重新赋值就比较重了,所以Vue也提供了直接监听嵌套属性变化的途径:

通过路径监听内部数据

watch: {'counter.up': function(newV, oldV) {console.log('counter.up change to %d from %d', newV, oldV);},'counter.down': function(newV, oldV) {console.log('counter.down change to %d from %d', newV, oldV);},
}

通过这种方式可以避免使用deep造成的性能消耗问题,当只对某内部属性变化作出响应的场景下比较合适,但仍要注意监听的路径数据仍是复杂数据时的场景。

初始化变量触发监听回调

使用watch监听变化时,给变量初始值不会触发监听函数,如果像要改变这个默认设定可以使用immediate参数,其用法和deep类似:

watch: {counter: {handler: function(newV, oldV) {console.log('counter change to %o from %o', newV, oldV);},immediate: true,}
}

这样在赋初值时就会触发监听函数,其中第一个参数为初始值,第二个参数为undefined

总结

使用watch可以监听属性的变化,且其使用方式也不少,理解每种方式的使用场景能为开发节省时间,优化性能。

  • watch使用文档
  • Vue Reactivity原理
  • computed vs watch

Vue如何正确使用watch监听属性变化相关推荐

  1. Vue监听器的基本使用(监听属性-深度监听和立即执行)

    一:vue监听器-基本使用 语法是: watch: {"被监听的属性名" (newVal, oldVal){}} 方便理解,示例代码: <template><di ...

  2. vue用watch监听属性变化

    比如子组件有个属性叫flag_t,父组件会修改子组件的这个数据的值,想要在子组件中监听这个变化并执行相应的函数,如下 watch:{flag_t(){console.log("flag_t变 ...

  3. Vue中使用watch来监听数据变化

    写法一: methods:{//监听isMD upProp(){if(this.isMD){//如果isMD等于true 就把storeManagerName赋值给isStoreManagerName ...

  4. Vue计算属性和监听属性

    一.计算属性 计算属性关键词: computed.计算属性在处理一些复杂逻辑时是很有用的. 可以看下以下反转字符串的例子: <div id="app">{{ messa ...

  5. Vue.js 监听属性简单实例

    Vue.js 监听属性 watch,可以通过 watch 来响应数据的变化. watch:用来监听每一个属性的变化     watch这个对象里面都是函数,函数的名称是data中的属性名称,watch ...

  6. vue 组件属性监听_Vue.js 监听属性

    # Vue.js 监听属性 本章节,我们将为大家介绍 Vue.js 监听属性 watch,我们可以通过 watch 来响应数据的变化: ~~~ Vue 测试实例 - 菜鸟教程(runoob.com) ...

  7. Vue.js:监听属性

    ylbtech-Vue.js:监听属性 1.返回顶部 1. Vue.js 监听属性 本章节,我们将为大家介绍 Vue.js 监听属性 watch,我们可以通过 watch 来响应数据的变化: 实例 & ...

  8. VUE之监听属性 watch

    <!DOCTYPE html> <html><head><meta charset="UTF-8"><title>VUE ...

  9. vue计算属性computed与监听属性watch的基本使用

    目录 Vue.js 计算属性 Vue.js 监听属性 Vue.js 计算属性 计算属性关键词: computed. 计算属性在处理一些复杂逻辑时是很有用的. 反转字符串的示例 <!DOCTYPE ...

最新文章

  1. 敏捷团队迭代交付能力计算模型
  2. zoj 3627(贪心)
  3. OSError: [WinError 126] 找不到指定的模块
  4. Springboot工程下使用mybatis反向工程
  5. mysql 自动执行语句_MYSQL 定时自动执行任务
  6. arcgis desktop 10.1 license manager无法启动问题解决
  7. python怎样安装wordcloud(词云)文件
  8. c#字符串的格式化输出
  9. CLM陆面过程模式实践技术应用
  10. 论单片机IO引脚驱动能力的提高
  11. 有哪些在成都开了 20 年以上的味道不错的小饭馆
  12. 3月13日云栖精选夜读 | Serverless 风暴来袭,前端工程师如何应对?...
  13. 持续集成/持续部署(1)Git Gitlab
  14. 荣耀 6p android 5.0,荣耀6/6Plus更新EMUI 5.6.1开发版
  15. 滑板底盘能否“跑起来”?一文读懂滑板底盘
  16. JAVA EE Code Quality / Sonar / findbugs / checkstyle / cobertura(coverage) / PMD
  17. 刷脸支付生活中普及太广民众满意度甚高
  18. WinForm中实现通用的弹窗提示框
  19. COMSOL中的动网格
  20. os系统共享的 不显示计算机,Windows与Mac OS共享文件-windows无法访问指定设备路径或文件...

热门文章

  1. 「Nginx实战」中学到的东西用在面试上,面试官都被怼得哑口无言
  2. layer出现Uncaught ReferenceError: layer is not defined错误
  3. 阿里云交互式分析与Presto对比分析及使用注意事项
  4. 第二十五期 总结《路由器就是开发板》
  5. python收益风险点图_AAVE当前风险与收益是否有偏差?如何评估DeFi投资组合?
  6. 描述计算机内存的参数,电脑组装内存知识,你不能不知的内存参数介绍
  7. 测试用例设计——微信发朋友圈(详细)
  8. 2020-2021 ICPC - Gran Premio de Mexico - Repechaje
  9. 关于Matplotlib作图时中文字体无法显示问题
  10. WMS系统--移库逻辑