vue watch监听不到对象,探究 watch 原理
最近使用vue watch时,在某些模块监听不到对象的改变,无法触发回调函数。
解决:
使用watch监听对象时,只能监听到该对象初始化时已存在的key值。
如下例监听user对象,在初始化时没有age属性,那在mounted中给user.age赋值后不会触发watch中的回调:
var app = new Vue({
el: '#app',
data: {
user: {
name: 'zhangsan'
}
},
mounted() {
var _this = this
setTimeout(() => {
_this.user.age = 10
},2000)
},
watch: {
user: {
handler (val) {
console.log('user update')
},
deep:true
}
}
})
若想监听到这个变化,需要给user初始化的age:
data: {
user: {
name: 'zhangsan',
age: 1
}
},
问题原因及vue watch原理:
这个问题其实是比较低级的错误,说明对vue的设计原理和理念还是理解太浅。watch的基本用法这里不再赘述,下面通过遇到的这个问题,探究一下watch对object类型进行监听的用法和原理。
通过官方文档我们知道,当监听的目标用对象进行配置时,共有三个配置属性:
watch: {
a:{
handler: function (val, oldVal) { /* ... */ },
immediate:true,
deep: true
}
}
首先,handler是vue中定义好的属性名,在用对象配置时,回调函数只能写在handler中。如下图源码所示,在creatWatcher时,会验证传入的配置项handler是否为一个纯对象类型,如果是对象类型,则会取handler.handler作为真正的回调函数;而下面的代码则是只传递方法名或方法实体的处理逻辑。
关于deep属性,大家都知道vue的绑定原理是建立在Object.defineProperty的set和get方法上的。给某个属性绑定set和get之后,只有改变该属性本身时,才会触发set和get的回调函数,而改变其内部属性时不会触发。所以在vue内部创建watcher时会有一个traverse方法,当配置deep为true时,调用traverse遍历其下每一个子属性。如下源代码:
而我们又知道vue只有在组件初始化时,会对data中数据进行set和get的绑定。这也是为什么在后续的业务逻辑中,给某个对象插入新属性时不会触发watch监听的原因。
immediate属性为true时,watcher创建后会立刻执行回调,这点不需要过多的介绍。
vue watch监听不到对象,探究 watch 原理的更多相关文章
- 设计模式(5): vue 不监听绑定的变量
概述 最近最近做项目的时候总会思考一些大的应用设计模式相关的问题,我把自己的思考记录下来,供以后开发时参考,相信对其他人也有用. 绑定变量 一般情况下,如果我们需要在组件中使用某个变量,会这么使用: ...
- vue时时监听input输入框中 输入内容 写法
Vue input 监听 使用 v-on:input="change" 实现即可 App.vue <template> <div> <md-field ...
- Vue 事件监听实现导航栏吸顶效果(页面滚动后定位)
Vue 事件监听实现导航栏吸顶效果(页面滚动后定位) Howie126313 关注 2017.11.19 15:05* 字数 100 阅读 3154评论 0喜欢 0 所说的吸顶效果就是在页面没有滑动之 ...
- 详解Vue 如何监听Array的变化
详解Vue 如何监听Array的变化:https://www.jb51.net/article/162584.htm
- 9.Vue.js 监听属性
本章节,我们将为大家介绍 Vue.js 监听属性 watch,我们可以通过 watch 来响应数据的变化. 以下实例通过使用 watch 实现计数器: <div id = "app&q ...
- vue 监听变量或对象
注意:监听的对象必须已经在data中声明了 data: { a: 1, b: 2, c: 3, d: 4, e: { f: { g: 5 } } }, watch: { a: function (va ...
- vue watch监听对象及对应值的变化
data:{ a:1, b:{ value:1, type:1, } }, watch:{ a(val, oldVal){//普通的watch监听 console.log("a: " ...
- Echarts图标宽度变成100px,让图表宽度随着父元素自动适应,Vue实时监听宽度的变化,这可能是史上最好的解决方案!
最近工作中element后台管理使用Echarts图表,本后台项目分图表模式和列表模式,使用display控制显示隐藏,这样就引出了本文的问题. 问题1:Echarts图标宽度变成100px? 问题2 ...
- Vue -- 数据监听
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
随机推荐
- Spring与Web环境集成
1. Spring与Web环境集成 1.1 ApplicationContext应用上下文获取方式 应用上下文对象是通过new ClasspathXmlApplicationContext(sprin ...
- 没有它你的DevOps是玩不转的,你信不?
摘要:架构的选择对于DevOps的实践是至关重要的,从某种程度上来说,架构就是DevOps这场战役的粮草,它是支撑着DevOps成功落地的重要前提. 善用兵者,役不再籍,粮不三载.取用于国,因粮于敌, ...
- POJ2466 棋盘覆盖
一张\(n*m\)的棋盘,有\(k\)个点不能被覆盖,问其余点能不能被\(1*2\)的小矩形完全覆盖,多测 这题先输入\(m\)是什么鬼啊!!! 其实是一个比较裸的二分图判定,把\(k\)个点挖去然后 ...
- 【题解】AcWing 193. 算乘方的牛
原题链接 题目描述 约翰的奶牛希望能够非常快速地计算一个数字的整数幂P(1 <= P <= 20,000)是多少,这需要你的帮助. 在它们计算得到最终结果的过程中只能保留两个工作变量用于中 ...
- 算法-数位dp
算法-数位dp 前置知识: \(\texttt{dp}\) \(\texttt{Dfs}\) 参考文献 https://www.cnblogs.com/y2823774827y/p/10301145. ...
- Java集合源码分析(六)——ConcurrentHashMap
目录 简介 源码分析 父类 接口 字段 内部类 1.链表节点结构 2.树根结构 3.树节点结构 方法 1.构造方法 2.基本并发方法 3.初始化表数组的操作 4.修改添加元素 5.统计元素数量 6.扩 ...
- nginx: [emerg] bind() to 0.0.0.0:80 failed (48: Address already in use)
Mac上启动nginx报如上错误,原因是80端口已被占用,可能有些服务未能成功关闭. 解决:键入命令 sudo nginx -s stop ( 或 sudo nginx -s quit) ,然后 s ...
- mybaties 使用注解注入动态sql (if-else)-转义字符
看到网上使用注解动态注入sql都是判断参数是否为空,我做项目的时候需要判断参数是否为字符串,需要对引号进行转义,所以把代码贴过来了. 注意:test表达式不能引用传入的参数,直接使用参数即可----- ...
- ThreadX——IPC应用之信号量
一.应用简介 在RTOS的应用开发中,信号量也是经常使用到的一种用于多任务之间信息同步.资源互斥访问的一种手段,常用于协调多个任务访问同一资源的场景.信号量又分为计数信号量和互斥信号量.计数信号量可以 ...
- 设置非root账号不用sudo直接执行docker命令
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...