<div>
<p>FullName: {{fullName}}</p>
<p>FirstName: <input type="text" v-model="firstName"></p>
</div> new Vue({
el: '#root',
data: {
firstName: 'Dawei',
lastName: 'Lou',
fullName: ''
},
watch: {
firstName(newName, oldName) {
this.fullName = newName + ' ' + this.lastName;
}
}
})

上面的代码的效果是,当我们输入firstName后,wacth监听每次修改变化的新值,然后计算输出fullName

handler方法和immediate属性

这里 watch 的一个特点是,最初绑定的时候是不会执行的,要等到 firstName 改变时才执行监听计算。那我们想要一开始就让他最初绑定的时候就执行改怎么办呢?我们需要修改一下我们的 watch 写法,修改过后的 watch 代码如下:

watch: {
firstName: {
handler(newName, oldName) {
this.fullName = newName + ' ' + this.lastName;
},
// 代表在wacth里声明了firstName这个方法之后立即先去执行handler方法
immediate: true
}
}

注意到handler了吗,我们给 firstName 绑定了一个handler方法,之前我们写的 watch 方法其实默认写的就是这个handler,Vue.js会去处理这个逻辑,最终编译出来其实就是这个handler

immediate:true代表如果在 wacth 里声明了 firstName 之后,就会立即先去执行里面的handler方法,如果为 false就跟我们以前的效果一样,不会在绑定的时候就执行。

deep属性

watch 里面还有一个属性 deep,默认值是 false,代表是否深度监听,比如我们 data 里有一个obj属性:

<div>
<p>obj.a: {{obj.a}}</p>
<p>obj.a: <input type="text" v-model="obj.a"></p>
</div> new Vue({
el: '#root',
data: {
obj: {
a: 123
}
},
watch: {
obj: {
handler(newName, oldName) {
console.log('obj.a changed');
},
immediate: true
}
}
})

当我们在在输入框中输入数据视图改变obj.a的值时,我们发现是无效的。受现代 JavaScript 的限制 (以及废弃 Object.observe),Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。

默认情况下 handler 只监听obj这个属性它的引用的变化,我们只有给obj赋值的时候它才会监听到,比如我们在 mounted事件钩子函数中对obj进行重新赋值:

mounted: {
this.obj = {
a: '456'
}
}

这样我们的 handler 才会执行,打印obj.a changed

相反,如果我们需要监听obj里的属性a的值呢?这时候deep属性就派上用场了!

watch: {
obj: {
handler(newName, oldName) {
console.log('obj.a changed');
},
immediate: true,
deep: true
}
}

deep的意思就是深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器,但是这样性能开销就会非常大了,任何修改obj里面任何一个属性都会触发这个监听器里的 handler。

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

watch: {
'obj.a': {
handler(newName, oldName) {
console.log('obj.a changed');
},
immediate: true,
// deep: true
}
}

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

注销watch

为什么要注销 watch?因为我们的组件是经常要被销毁的,比如我们跳一个路由,从一个页面跳到另外一个页面,那么原来的页面的 watch 其实就没用了,这时候我们应该注销掉原来页面的 watch 的,不然的话可能会导致内存溢出。好在我们平时 watch 都是写在组件的选项中的,他会随着组件的销毁而销毁。

const app = new Vue({
template: '<div id="root">{{text}}</div>',
data: {
text: 0
},
watch: {
text(newVal, oldVal){
console.log(`${newVal} : ${oldVal}`);
}
}
});

但是,如果我们使用下面这样的方式写 watch,那么就要手动注销了,这种注销其实也很简单

const unWatch = app.$watch('text', (newVal, oldVal) => {
console.log(`${newVal} : ${oldVal}`);
}) unWatch(); // 手动注销watch

app.$watch调用后会返回一个值,就是unWatch方法,你要注销 watch 只要调用unWatch方法就可以了。

2.watch监听路由

我们可以使用watch来进行路由的监听

watch: {
changeShowType(value) {
console.log("-----"+value);
},
'$route'(to,from){
console.log(to); //to表示去往的界面
console.log(from); //from表示来自于哪个界面
if(to.path=="/shop/detail"){
console.log("商品详情");
}
}
},

Vue.js中 watch的理解以及深度监听的更多相关文章

  1. 关于vue.js中slot的理解

    slot这块看官网文档,起初有点不懂,仔细研究还是最终理解了,slot是用来干嘛的呢,先看下一个例子: <script src="https://unpkg.com/vue/dist/ ...

  2. vue.js中$emit的理解

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

  3. JS 中的事件绑定、事件监听、事件委托

    事件绑定 要想让 JavaScript 对用户的操作作出响应,首先要对 DOM 元素绑定事件处理函数.所谓事件处理函数,就是处理用户操作的函数,不同的操作对应不同的名称. 在JavaScript中,有 ...

  4. JS 中的事件绑定、事件监听、事件委托是什么?

    在JavaScript的学习中,我们经常会遇到JavaScript的事件机制,例如,事件绑定.事件监听.事件委托(事件代理)等.这些名词是什么意思呢,有什么作用呢? 事件绑定 要想让 JavaScri ...

  5. Vue.js中 watch(深度监听)的最易懂的解释

    <div> <p>FullName: {{fullName}}</p> <p>FirstName: <input type="text& ...

  6. Vue.js中 watch(深度监听)的最易懂的解释[转]

    https://blog.csdn.net/qq_36688143/article/details/81287535 taskData: { handler(v) { // watch 方法其实默认写 ...

  7. 对Vue.js $watch方法的理解

    博主最近对着vue.js的官方教程在自学vue.js,博主自幼愚钝,在教程中真的是好多点都不太理解,接下来要说的这个$watch方法就是其中一个不太理解的点了.咱们先来看一下对于$watch方法在vu ...

  8. vue.js中,input和textarea上的v-model指令到底做了什么?

    v-model是 vue.js 中用于在表单表单元素上创建双向数据绑定,它的本质只是一个语法糖,在单向数据绑定的基础上,增加了监听用户输入事件并更新数据的功能: 对,它本质上只是一个语法糖,但到底是一 ...

  9. 实例分析Vue.js中 computed和methods不同机制

    在vue.js中,有methods和computed两种方式来动态当作方法来用的 1.首先最明显的不同 就是调用的时候,methods要加上() 2.我们可以使用 methods 来替代 comput ...

随机推荐

  1. console.log()、console.info()、console.debug()的区别

    onsole.log().console.info().console.debug()的作用都是在浏览器控制台打印信息的. 使用最多的是console.log().console.info()和con ...

  2. C# 后台获取GridView列表的值

    int rowIndex = ((GridViewRow)((Button)sender).NamingContainer).RowIndex;//获取gridview中的行号            ...

  3. Switch开关在element-ui表格中点击没有效果解决方法

    <el-table-column label="三审" align="center"> <template slot-scope=" ...

  4. requests爬虫get请求

    1.简单get请求 url = 'https://www.baidu.com' headers = { 'accept': 'text/html,application/xhtml+xml,appli ...

  5. Mysql8.0.17安装(windows10)

    1.因为系统重装  又双叒叕开始了装mysql数据库 下载安装包 https://dev.mysql.com/downloads/mysql/ 2.解压到你想安装的地方 3.解压完是没有图红色框中的文 ...

  6. workman 使用心得

    1.  服务端调试: 直接在 Events.php 中 echo 变量,   即可在  命令行工具中  看到输出的信息. 以便进行调试. 2. 客户端调试: 由于是js代码, 可以直接 用 conso ...

  7. Python日记(二):Python之禅

    The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Si ...

  8. Flink原理(四)——任务及调度

    本文是博主阅读官网文档.博客及书籍后自己所思所得,若是存在有误的地方,欢迎留言分享,谢谢! 一.任务调度 Flink是通过task slot的来定义执行资源的,为优化资源的利用率,Flink通过slo ...

  9. C++(四十二) — 函数模板多态

     1.函数模板(参数多态) 相当于一个函数发生器,参数多态,可以重载. 普通函数和模板函数的本质区别: 普通函数的调用,可以进行隐式的类型转换: 函数模板的调用,使用类型参数化,严格按照类型进行匹配, ...

  10. pip---cannot import name main解决方案

    .先来看下Python不同版本对应的路径 which python3. which python3. .使用update-alternatives --install建立链接 sudo update- ...