每天一点点之vue框架 watch监听变量(深度监听)
- <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框架 watch监听变量(深度监听)的更多相关文章
- 每天一点点之vue框架开发 - 引入Jquery
1. 安装jquery npm install jquery --save-dev 2.在build/webpack.base.conf.js中添加如下内容 var webpack = require ...
- 每天一点点之vue框架开发 - 使用vue-router路由
1.安装路由(安装过的跳过此步) // 进入项目根目录 cd frontend // 安装 npm install vue-router --save-dev 2.在入口文件main.js中引入路由 ...
- 每天一点点之vue框架开发 - vue坑-This relative module was not found
94% asset optimization ERROR Failed to compile with 1 errors This relative module was not found: * . ...
- vue2.0中watch总结:普通监听和深度监听
watch:{} 是一个对象,一定要当成对象来用,可监听数据,是vue中数据发生变化进行处理的函数, 它有三个选项 第一个handler:其值是一个回调函数.即监听到变化时应该执行的函数.第二个是de ...
- 每天一点点之vue框架开发 - 如何在一个页面调用另一个同级页面的方法
使用场景: 页面分为header.home.footer三部分,需要在home中调用header中的方法,这两个没有相互引入 官方给出方法: api传送门 在项目中实现: 1.首先同一个vue实例来调 ...
- 每天一点点之vue框架开发 - vue-router路由在循环中携带参数
场景:要实现一个标签云,通过循环把标签渲染,然后单击标签的时候实现跳转,跳转路由一样,通过唯一参数来实现请求不同的数据 因此,就需要在for循环中来携带参数,本节所讲的是路由使用对象的形式(别名)来实 ...
- 每天一点点之vue框架开发 - History 模式下线上路由报404错误
vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载. 如果不想要很丑的 hash,我们可以用路由的 his ...
- 每天一点点之vue框架开发 - 部署到线上
1.在项目根目录下运行如下命令 npm run build 会生成一个dist目录, 2.然后将dist目录上传至服务器就可以访问页面了,不需要配置vue环境了.
- 每天一点点之vue框架开发 - 引入bootstrap
只使用css样式 如果在你的项目中只是使用css样式,那就不需要安装,直接全局引入样式就好 <link rel="stylesheet" href="https ...
随机推荐
- 总结 jion,group join 基于方法的查询与查询表达式 对比
数据源: 代码: using (tempdbEntities context = new tempdbEntities()) { #region 基于方法的查询 Console.WriteLine(& ...
- IE浏览器清浮动
.cfx:after,.cfx:before{content:" ";display:table;}.cfx:after{clear:both;}.cfx{*zoom:1;} 今天 ...
- 解决:hudson.plugins.git.GitException: Could not init
解决:
- PyQt5剪切板操作
1.使用剪切板import sys,mathfrom PyQt5.QtWidgets import *from PyQt5.QtGui import *from PyQt5.QtCore import ...
- ROM, RAM, NVRAM and Flash Memory on Cisco Routers
当谈到路由器有多少内存以及哪些内存做什么时,有时人们会感到困惑. 您应该熟悉4个内存术语,在升级路由器的IOS之前应检查其中2个. 这些是以下内容: ROM:ROM代表只读存储器. 它存储System ...
- ASA-ACL类型
安全设备支持下面5种不同类型的ACl: 标准ACL 扩展ACL(可匹配v4&v6流量) EtherType ACL (以太网类型ACL) WebType ACL(Web类型ACL) 1.标准A ...
- c#活动目录操作
c#活动目录操作 https://www.cnblogs.com/ahuo/archive/2007/03/16/676853.html 添加引用 System.DirectoryServices导 ...
- js实现配置菜品规格时,向后台传一个json格式字符串
由于本公司做的是订餐平台,那么在上传菜品时,需要配置菜品规格,比如份量(大中小),味道(猛辣,中辣,微辣) 由于这些数据,在表的设计时 没有保存到菜品表,那么在点击保存菜品数据时,配置规格这块数据,我 ...
- stm32CubeMx lwip + freeRTOS
MCU: STM32F429IGT6 工具:STM32CubeMx 版本号 5.0.0 Keil uVersion5 目的:使用LWIP 实现简单的网络连通 一 简介 LWIP(Light Wei ...
- 3种使用MQ实现分布式事务的方式
1.保证消息传递与一致性 1.1生产者确保消息自主性 当生产者发送一条消息时,它必须完成他的所有业务操作. 如下图: 这保证消费者接受到消息时,生产者已处理完毕相关业务,也就是1PC的基础. 1.2 ...