Vue如何正确使用watch监听属性变化
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.up或counter.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监听属性变化相关推荐
- Vue监听器的基本使用(监听属性-深度监听和立即执行)
一:vue监听器-基本使用 语法是: watch: {"被监听的属性名" (newVal, oldVal){}} 方便理解,示例代码: <template><di ...
- vue用watch监听属性变化
比如子组件有个属性叫flag_t,父组件会修改子组件的这个数据的值,想要在子组件中监听这个变化并执行相应的函数,如下 watch:{flag_t(){console.log("flag_t变 ...
- Vue中使用watch来监听数据变化
写法一: methods:{//监听isMD upProp(){if(this.isMD){//如果isMD等于true 就把storeManagerName赋值给isStoreManagerName ...
- Vue计算属性和监听属性
一.计算属性 计算属性关键词: computed.计算属性在处理一些复杂逻辑时是很有用的. 可以看下以下反转字符串的例子: <div id="app">{{ messa ...
- Vue.js 监听属性简单实例
Vue.js 监听属性 watch,可以通过 watch 来响应数据的变化. watch:用来监听每一个属性的变化 watch这个对象里面都是函数,函数的名称是data中的属性名称,watch ...
- vue 组件属性监听_Vue.js 监听属性
# Vue.js 监听属性 本章节,我们将为大家介绍 Vue.js 监听属性 watch,我们可以通过 watch 来响应数据的变化: ~~~ Vue 测试实例 - 菜鸟教程(runoob.com) ...
- Vue.js:监听属性
ylbtech-Vue.js:监听属性 1.返回顶部 1. Vue.js 监听属性 本章节,我们将为大家介绍 Vue.js 监听属性 watch,我们可以通过 watch 来响应数据的变化: 实例 & ...
- VUE之监听属性 watch
<!DOCTYPE html> <html><head><meta charset="UTF-8"><title>VUE ...
- vue计算属性computed与监听属性watch的基本使用
目录 Vue.js 计算属性 Vue.js 监听属性 Vue.js 计算属性 计算属性关键词: computed. 计算属性在处理一些复杂逻辑时是很有用的. 反转字符串的示例 <!DOCTYPE ...
最新文章
- 敏捷团队迭代交付能力计算模型
- zoj 3627(贪心)
- OSError: [WinError 126] 找不到指定的模块
- Springboot工程下使用mybatis反向工程
- mysql 自动执行语句_MYSQL 定时自动执行任务
- arcgis desktop 10.1 license manager无法启动问题解决
- python怎样安装wordcloud(词云)文件
- c#字符串的格式化输出
- CLM陆面过程模式实践技术应用
- 论单片机IO引脚驱动能力的提高
- 有哪些在成都开了 20 年以上的味道不错的小饭馆
- 3月13日云栖精选夜读 | Serverless 风暴来袭,前端工程师如何应对?...
- 持续集成/持续部署(1)Git Gitlab
- 荣耀 6p android 5.0,荣耀6/6Plus更新EMUI 5.6.1开发版
- 滑板底盘能否“跑起来”?一文读懂滑板底盘
- JAVA EE Code Quality / Sonar / findbugs / checkstyle / cobertura(coverage) / PMD
- 刷脸支付生活中普及太广民众满意度甚高
- WinForm中实现通用的弹窗提示框
- COMSOL中的动网格
- os系统共享的 不显示计算机,Windows与Mac OS共享文件-windows无法访问指定设备路径或文件...
热门文章
- 「Nginx实战」中学到的东西用在面试上,面试官都被怼得哑口无言
- layer出现Uncaught ReferenceError: layer is not defined错误
- 阿里云交互式分析与Presto对比分析及使用注意事项
- 第二十五期 总结《路由器就是开发板》
- python收益风险点图_AAVE当前风险与收益是否有偏差?如何评估DeFi投资组合?
- 描述计算机内存的参数,电脑组装内存知识,你不能不知的内存参数介绍
- 测试用例设计——微信发朋友圈(详细)
- 2020-2021 ICPC - Gran Premio de Mexico - Repechaje
- 关于Matplotlib作图时中文字体无法显示问题
- WMS系统--移库逻辑