vue中wath的源码实现
前言
阅读本节,需要理解vue的数据驱动原理。
看这样一段代码
new Vue({
data: {
msg: 'hello',
say: 'hello world',
},
watch: {
msg(newVal) {
this.say = newVal + ' world';
}
}
})
vue的data包括2个属性msg和say,watch中监听msg并更新say的值。
源码实现
1. new Vue
function Vue (options) {
if ("development" !== 'production' &&
!(this instanceof Vue)
) {
warn('Vue is a constructor and should be called with the `new` keyword');
}
this._init(options);
}
new Vue会执行原型上的_init方法, _init方法中hi调用 initState,这个方法会初始化所有状态相关内容
2. initWatch
initStatus会判断如果我们定义了watch则执行initWatch
function initWatch (vm, watch) {
for (var key in watch) {
var handler = watch[key];
if (Array.isArray(handler)) {
for (var i = 0; i < handler.length; i++) {
createWatcher(vm, key, handler[i]);
}
} else {
createWatcher(vm, key, handler);
}
}
}
这段代码意思是如果watch声明了一个数组,则遍历数组并调用createWatcher,如果不是数组就直接调用createWatcher传递过去。这就证明,watch我们可以声明多个处理函数。
3. createWatcher
createWatcher主要工作是处理传入值,传入不同的值,做不同的兼容处理
function createWatcher (
vm,
expOrFn,
handler,
options
) {
// 如果handler是对象,则获取handler下面的handler属性当作watch的执行函数
if (isPlainObject(handler)) {
options = handler;
handler = handler.handler;
}
// 如果handler是字符串,则获取vue原型上的方法
if (typeof handler === 'string') {
handler = vm[handler];
}
// 调用vue原型上的$watch
return vm.$watch(expOrFn, handler, options)
}
通过以上我们可以看出,watch定义有很多种类型,比如:
new Vue({
watch: {
// 字符串
test1: 'handleTest',
// 对象
test2: {
handler(newVal) {
// ....
}
}
},
methods: {
handleTest(newVal) {
// ...
}
}
})
4. vm.$watch
Vue.prototype.$watch = function (
expOrFn,
cb,
options
) {
var vm = this;
if (isPlainObject(cb)) {
return createWatcher(vm, expOrFn, cb, options)
}
options = options || {};
options.user = true;
// new 一个Watcher实例
var watcher = new Watcher(vm, expOrFn, cb, options);
if (options.immediate) {
cb.call(vm, watcher.value);
}
return function unwatchFn() {
watcher.teardown();
}
};
通过以上代码可以看出,watch的创建最终其实是vue内部创建了一个Watcher实例。那么Watcher是vue中很重要的一部分,它是数据驱动不可缺少的一部分。
接下来大概讲一下new Watcher的功能是什么样的。
5. new Watcher
vue在拿到了要监听的属性和属性更新执行的函数后,new Watcher创建一个Watcher。
Watcher是订阅者,它“监听更新行为”并执行更新函数。
为什么双引号?其实不是它在监听。以最初的代码为例更新步骤如下:
1. vue内部new Watcher创建一个Watcher实例
2. Watcher实例创建时会将自己添加到data.msg的Observer中(数据驱动原理知识)
3. 当我们改变msg值时,msg Observer会通知所有被观察者,其中就包括以上Watcher。(数据驱动原理知识)
4. Watcher触发更新并且执行回调,因此执行了我们声明的函数。
完结
watch的实现很简单,这里需要vue的数据驱动原理,由Object.defileProperty、Dep、Watcher几部分实现。不了解的可以先去学习这部分内容。
vue中wath的源码实现的更多相关文章
- Vue.js 2.0源码解析之前端渲染篇
一.前言 Vue.js框架是目前比较火的MVVM框架之一,简单易上手的学习曲线,友好的官方文档,配套的构建工具,让Vue.js在2016大放异彩,大有赶超React之势.前不久Vue.js 2.0正式 ...
- 如何实现全屏遮罩(附Vue.extend和el-message源码学习)
[Vue]如何实现全屏遮罩(附Vue.extend和el-message源码学习) 在做个人项目的时候需要做一个类似于电子相册浏览的控件,实现过程中首先要实现全局遮罩,结合自己的思路并阅读了(饿了么) ...
- 探秘Tomcat(一)——Myeclipse中导入Tomcat源码
前言:有的时候自己不知道自己是井底之蛙,这并没有什么可怕的,因为你只要蜷缩在方寸之间的井里,无数次的生活轨迹无非最终归结还是一个圆形:但是可怕的是有一天你不得不从井里跳出来生活,需要重新审视井以外的生 ...
- Scala 深入浅出实战经典 第65讲:Scala中隐式转换内幕揭秘、最佳实践及其在Spark中的应用源码解析
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- Scala 深入浅出实战经典 第61讲:Scala中隐式参数与隐式转换的联合使用实战详解及其在Spark中的应用源码解析
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载: 百度云盘:http://pan.baidu.com/s/1c0noOt ...
- Scala 深入浅出实战经典 第60讲:Scala中隐式参数实战详解以及在Spark中的应用源码解析
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- Scala 深入浅出实战经典 第48讲:Scala类型约束代码实战及其在Spark中的应用源码解析
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- [原创]在Windows和Linux中搭建PostgreSQL源码调试环境
张文升http://ode.cnblogs.comEmail:wensheng.zhang#foxmail.com 配图太多,完整pdf下载请点这里 本文使用Xming.Putty和VMWare几款工 ...
- Android: 在WebView中获取网页源码
1. 使能javascript: ? 1 webView.getSettings().setJavaScriptEnabled(true); 2. 编写本地接口 ? 1 2 3 4 5 final c ...
随机推荐
- 把数字翻译成字符串 --剑指offer 46题
# 给一个字符串,按如下规则把它翻译成字符串:1翻译成a,2翻译成b,...25翻译成z:一个数可以有多种翻译方式,比如122可以翻译成abb和kb还可以翻译成aw即3种翻译方式.计算一个数字有几种翻 ...
- 微服务-技术专区-链路追踪(pinpoint)-部署使用
https://naver.github.io/pinpoint/ https://github.com/naver/pinpoint 背景 随着项目微服务的进行,微服务数量逐渐增加,服务间的调用也越 ...
- Java原理领悟-JMM(java内存模型认知)
总线锁.缓存锁.MESI缓存一致性协议.CPU 层面的内存屏障 1.JMM定义: Java Memory Model(java内存模型)是一系列的Java虚拟机平台对开发者提供的多线程环境下的内存可见 ...
- C#关键字扫盲——Tuple(元组类) 、ValueTuple(值元组)
原文:C#关键字扫盲--Tuple(元组类) .ValueTuple(值元组) 版权声明:本文为博主原创文章,随意转载. https://blog.csdn.net/Michel4Liu/articl ...
- android中读取SD卡上的数据
通过Context的openFileInput或者openFileOutput打开的文件输入输出流是操作应用程序的数据文件夹里的文件,这样存储的大小比较有限,为了更好的存取应用程序的大文件数据,应用程 ...
- less&sass
定义: less是一种动态样式语言,对css赋予了动态语言的特性,比如变量.继承.运算.函数,既可以运行在客户端,也可以运行在服务器端,依赖JavaScript sass是一种动态语言,属于缩排语 ...
- android studio安装中出现Failed to install Intel HAXM错误的解决方法
1.问题分析 从下面可以知道安装Intel HAXM失败,请检查haxm_silent_run.log这篇日志. (1)先了解一下什么是Intel HAXM Intel代表的是英特尔,HAXM的全程是 ...
- master挂了的话pm2怎么处理 使用pm2方便开启node集群模式
本文为转载 Introduction As you would probably know, Node.js is a platform built on Chrome's JavaScript ru ...
- informix 计算 日期之差
原文地址:http://blog.chinaunix.net/uid-678894-id-3138829.html https://blog.csdn.net/zhengqiqiqinqin/arti ...
- python补充4
一 如何判断一个对象是不是函数类型 #方法一def func(arg): if callable(arg): print("是函数"+arg()) else: print(arg) ...