关于watch
watch和computed是姊妹篇,前言同上。
为啥姊妹呢,因为computed初始化完了就是初始化watch:
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);
}
}
}
这个方法没啥好解说的,直接到createWatcher:
function createWatcher (
vm,
expOrFn,
handler,
options
) {
if (isPlainObject(handler)) {
options = handler;
handler = handler.handler;
}
if (typeof handler === 'string') {
handler = vm[handler];
}
return vm.$watch(expOrFn, handler, options)
}
从上面的代码可以看出初始化的时候定义在watch上的那些key-value和调用实例的$watch走的是一回事。所以还是看看$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;
var watcher = new Watcher(vm, expOrFn, cb, options);
if (options***mediate) {
try {
cb.call(vm, watcher.value);
} catch (error) {
handleError(error, vm, ("callback for immediate watcher \"" + (watcher.expression) + "\""));
}
}
return function unwatchFn () {
watcher.teardown();
}
};
}
看到没,又是watcher,这里的options是undefined,但是要注意到,options.user = true; 这个很重要是因为刷新任务队列的时候watch里的watcher的cb回调函数就是根据这个参数去调用的。我在写到这里的时候其实想吐槽一句vue就是vue框架的的整个机制大到vuex,vue-router小到这种数据的相应式绑定都跟watcher有关,不过我第一次发现这个的时候倒是觉着挺妙的,其他的倒也没啥。
(n年后的补充:一个工具在一个框架内部要去实现响应式更新,无论路由也好,状态管理也好,其,要实现更新,更定是要利用框架现有的机制的,vue的watcher,react的setstate等等,不然能咋办呢)
这个函数里需要注意到一个地方就是实例化watcher的时候,是吧当前watch的key传进去了,此时,expOrFn是一个字符串类型,这个时候,Watcher构造函数的执行是这样的:
this.getter = parsePath(expOrFn);
parsePath长这样:
function parsePath (path) {
if (bailRE.test(path)) {
return
}
var segments = path.split('.');
return function (obj) {
for (var i = 0; i < segments.length; i++) {
if (!obj) { return }
obj = obj[segments[i]];
}
return obj
}
}
返回的闭包函数就是当前watcher的getter,闭包了当前的'key',这个key也可以是‘key.key.key’,这个有啥用放到后边说,watcher走到最后一步的时候会调用watcher实例的get进行依赖收集,然后依赖收集的时候有这么一句:
value = this.getter.call(vm, vm);
所以再回到上边那个闭包函数中,此时调用的时候obj参数就引用了当前的vm,而下边的for循环则是一步步具体化watch要watch的路径,触发这条路径上所有的get,进行依赖收集,比方说我们watch了一个'key.key',那么vm['key'],vm['key']['key']会依次调用,此时watch里key值派生的watcher也被依赖收集机制 收集了进去。然后一个watch就这么初始化完毕啦。
随机推荐
- 【研究生学习】SNR、Eb/N0和Es/N0的关系
SNR.Eb/N0与Es/N0的关系 在模拟通信中,SNR是一个非常有用的指标 实例说明
- 鉄道旅行 (Railroad Trip)
题意 有 \(n\) 个城市, \(n-1\) 条道路.其中第 \(i\) 个城市和第 \(i+1\) 个城市由第 \(i\) 条道路连接.通过一条道路有两种付费方式:每次支付费用 \(a_i\) , ...
- Python 20个常用库
Requests.Kenneth Reitz写的最富盛名的http库.每个Python程序员都应该有它. Scrapy.如果你从事爬虫相关的工作,那么这个库也是必不可少的.用过它之后你就不会再想用别的 ...
- 新的学习历程-python1 Hello World
1 print('hello world!') 2 if 2 > 0: 3 print('ok') 4 print('yes') 5 6 x = 3; y = 4 7 print(x + y) ...
- GitHub访问缓慢
参考:https://www.cnblogs.com/liuchao888/p/11733996.html
- QML笔记
文章钢要: 1.qml基础知识 2.qml语言技巧 一.QML basic types QML Language提供的基础类型:int ,bool,string,double,real,var,url ...
- vue element 日期范围选择器限制:只能选今天之前的时间 || 只能选今天之后的时间 || 选取今天往后三天内
举例:只能选今天或者今天之后的时间(如下图) <el-date-picker clearable v-model="form.limitTime" type="da ...
- LESS-8
根据题目,这是一道布尔型注入.页面只有返回正常和不正常两种. payload: ' and substr(database(),1,1)='s' --+ 判断当前数据库名的第一个字母,是's'页面就 ...
- Qt 中文编译错误和运行显示乱码
Qt 中文编译错误 Qt error: C2001: 常量中有换行符 解决方法:菜单 --> 编辑 --> 选择编码(select Encoding)--> 文本编码 --> ...
- Firefox彻底禁用自动更新提示
实验版本:96 安装目录下新建文件夹:distribution 新建文件:policies.json 文件内容为: { "policies": { "DisableApp ...