首先看下watch所支持的用法,不然你不知道支持哪些用法。

var vm = new Vue({data: {a: 1,b: 2,c: 3,d: 4,e: {f: {g: 5}}},watch: {//平时相信都是这种写法居多  函数a: function (val, oldVal) {console.log('new: %s, old: %s', val, oldVal)},// 方法名  字符串,  我是没用过这种。。。冷门,关键源码里面有b: 'someMethod',// 深度 watcher  对象c: {handler: function (val, oldVal) { /* ... */ },deep: true},// 该回调将会在侦听开始之后被立即调用  也是对象d: {handler: function (val, oldVal) { /* ... */ },immediate: true},// 数组e: [function handle1 (val, oldVal) { /* ... */ },function handle2 (val, oldVal) { /* ... */ }],// watch vm.e.f's value: {g: 5}'e.f': function (val, oldVal) { /* ... */ }}
})
vm.a = 2 // => new: 2, old: 1

所以watch支持的写法有:数组、函数、对象、字符串

this.$watch('name', newName => {...})还可以有这种写法,说明vue2的时候就有vue3的影子了类似hooks那种用法,下面源码有介绍。

function initState(vm) {  // 初始化所有状态时vm._watchers = []  // 当前实例watcher集合const opts = vm.$options  // 合并后的属性... // 其他状态初始化if(opts.watch) {  // 如果有定义watch属性initWatch(vm, opts.watch)  // 执行初始化方法}
}---------------------------------------------------------function initWatch (vm, watch) {  // 初始化方法for (const key in watch) {  // 遍历watch内多个监听属性const handler = watch[key]  // 每一个监听属性的值if (Array.isArray(handler)) {  // 如果该项的值为数组for (let i = 0; i < handler.length; i++) {createWatcher(vm, key, handler[i])  // 将每一项使用watcher包装}} else {createWatcher(vm, key, handler) // 不是数组直接使用watcher}}
}---------------------------------------------------------function createWatcher (vm, expOrFn, handler, options) {if (isPlainObject(handler)) { // 如果是对象,参数移位options = handler  handler = handler.handler}if (typeof handler === 'string') {  // 如果是字符串,表示为方法名handler = vm[handler]  // 获取methods内的方法}return vm.$watch(expOrFn, handler, options)  // 封装
}

总结:

1.首先在new vue初始化阶段时候, 会在initState函数里面先判断是否有定义watch,有的话就执行initWatch

2.使用for in 遍历watch里面的每个key,这里比较有意思的是:watch支持数组函数,平时我们写法都是单个对象方式定义。如果传了数组函数就遍历该数组,调用createWatcher(vm, key, handler)函数。

3.createWatcher首先对 hanlder 的类型做判断,这里面只有2种判断,对象+字符串

3.1如果传的是对象就拿到它最终的回调函数。

3.2如果是字符串就是方法名,会直接映射到vm上面赋值给handler。

3.3 如果是函数就不用理会,直接vm.$watch

最后调用 vm.$watch(keyOrFn, handler, options) 函数,$watch 是 Vue 原型上的方法,它是在执行 stateMixin 的时候定义的

接下来看下$watch的内部实现:

Vue.prototype.$watch = function(expOrFn, cb, options = {}) {const vm = thisif (isPlainObject(cb)) {  // 如果cb是对象,当手动创建监听属性时return createWatcher(vm, expOrFn, cb, options)}options.user = true  // user-watcher的标志位,传入Watcher类中const watcher = new Watcher(vm, expOrFn, cb, options)  // 实例化user-watcherif (options.immediate) {  // 立即执行cb.call(vm, watcher.value)  // 以当前值立即执行一次回调函数}  // watcher.value为实例化后返回的值return function unwatchFn () {  // 返回一个函数,执行取消监听watcher.teardown()}
}---------------------------------------------------------------
总结下上面源码发现,this.$watch第二个参数可以传对象export default {data() {return {name: 'cc'}  },created() {第一种传对象:let obj={handler: function (val, oldVal) { /* ... */ },deep: true}this.unwatch1 = this.$watch('name', obj)第二种传函数:this.unwatch = this.$watch('name', newName => {...})this.unwatch()  // 取消监听   最后会返回一个函数取消}
}

vue2的 watch的理解(7)相关推荐

  1. vue2和vue3的区别(由浅入深)

    前言 vue2和vu3之前的区别,一直以来是面试必考题目,如何回答,回答的层次决定了面试者的对于vue2,3的理解,以及对于vue3目前稳定版本发展的方向的了解,即考察使用程度,又考察了学习能力,可以 ...

  2. vue2+vue3——36+

    vue2+vue3--36+ 尚硅谷 vue2 vue2 Vue监测数据的原理_数组[18:56] 数组 vue 查看 没有 set() get() 对象 有 get() set() 监测不到 不更新 ...

  3. Vue2.x全家桶学习笔记

    一.概述 1.1.什么是Vue ​ Vue 是一个 自底向上 逐层应用.注重 视图模块 .快捷构建 前端应用 的 渐进式框架 ! 1.2.为什么使用Vue ​ 随着项目规模的增大.业务流程的复杂度提升 ...

  4. Vue2.0 探索之路——生命周期和钩子函数的一些理解

    前言 在使用vue一个多礼拜后,感觉现在还停留在初级阶段,虽然知道怎么和后端做数据交互,但是对于mounted这个挂载还不是很清楚的.放大之,对vue的生命周期不甚了解.只知道简单的使用,而不知道为什 ...

  5. 【vue2.0进阶】轻松理解Vuex的3个核心概念

    上一节前端君和大家一起认识了Vuex,我们了解了Vuex是一个提供状态管理机制,相比使用传统的全局对象,它有两大优点,一个是它的状态存储是响应式的,另一个是要不能随意修改Vuex的状态,必须按照它的规 ...

  6. vue2.0中ckeckbox(复选框)的使用心得,及对click事件和change的理解

    最近在公司项目中使用vue2.0做开发,在使用checkbox时遇到了一些问题,首先我们先了解一下需求. 如上如所示,在上方复选框被点击时,更改下方p标签的文本内容为:复选框已被选中.并将p标签文字颜 ...

  7. vue2中vuex状态管理的理解(菜单面包板)

    本片理解基于vue2对应的Vuex文档,结合了官网文档以及众多前辈大佬所发布的帖子,由衷表示感谢. vuex的超详细讲解和具体使用细节记录 随着我们进一步扩展约定,即组件不允许直接变更属于 store ...

  8. 分析理解 vue2.x和3.0的响应式系统的异同

    前言 vue3.0国庆的时候刚发布了部分代码,之前学习过vue部分源码(都快忘完了,还是得记录,看完都会了,但是忘得比学得快多了...为了加深记忆和更好地理解应用,最近考虑把相关知识都写成博客)这里针 ...

  9. 一篇文章简单的盘点下 Vue3 与 Vue2 的差异性,让你更加理解 Vue

    希望本篇文章能帮你加深对 Vue 的理解,能信誓旦旦地说自己熟练Vue2/3.除此之外,也希望路过的朋友可以帮助我查漏补缺

最新文章

  1. 面向自动驾驶车辆的高效激光里程计(ICRA2021)
  2. U-Det:一种改进的双向特征网络U-Net结构用于肺结节分割
  3. 输出内容时后面显示乱码
  4. 缓存处理类(MemoryCache结合文件缓存)
  5. 几大科技公司在VR方面的布局是怎么样的?
  6. 八皇后时间复杂度_回溯算法 | 追忆那些年曾难倒我们的八皇后问题
  7. 《You Only Look Once: Unified, Real-Time Object Detection》YOLO一种实时目标检测方法 阅读笔记(未完成版)
  8. IDEA使用指南常用快捷键
  9. 将Myeclipse非maven项目,导入到IDEA
  10. The GDM user does not exist.Please correct gdm configration and restart gdm
  11. JS向NPAPI传递参数,并返回结果
  12. 小程序开发教程 | 来自小程序开发者的实例教程
  13. 初识 InnoDB存储引擎
  14. linux下od命令的使用教程,linux od命令详解
  15. 2021亚太杯数学建模C题全网成品论文+代码+详细思路+数据+参考文献
  16. 密码只靠大脑记好累,有没有试过用群晖NAS来记?
  17. 【JAVA学习】六、设计模式
  18. 根据身份证号判断该人的年龄、性别、出生年月日
  19. 用C语言将四个数字排列顺序(不重复)
  20. ffmpeg连接rtsp流提示Connection refused

热门文章

  1. CDN流量是什么,怎么计算?
  2. SpringBoot(七) 整合Mybatis
  3. NSG2 安装、运行备忘
  4. ps提示没有足够的ram
  5. !include: could not find: nsProcess.nsh
  6. 农作物病虫害识别进展概述(***)
  7. eclipse导入spring源码二(丢失的spring-asm-repack和spring-cglib-repack)
  8. mysql 数据表格切分_MySQL数据库垂直和水平切分
  9. html都有哪些事件,HTML有哪些事件属性?
  10. 【生活小捣鼓】登录PC端某网站,需要他人(不在身边)手机扫二维码,这时候该怎么办?