《Evan You 尤雨溪讲解 vue 源码及高级特性》笔记
码农天地 -前言
原视频链接请点击,视频中带你以 vue 开发者的视角来看其中的设计模式及高级特性,且包含许多底层实现,强烈推荐。
响应式原理React此处特指在前端中如何通过改动state
以更新view
。
/*
React
*/
let update;
const onStateChange = _update => {
update = _update;
}
const setState = newState => {
state = newState;
update();
}
onStateChange(() => {
view = render(state);
});
setState({a: 5});
在 React 中我们规定只能通过setState
函数来改变state
,如此一来便可以在每一次state
改变后调用render
来更新view
。
在 Vue 中可以直接通过改变 state
的值来改变 view
,而不必调用 setState
函数。这是通过 Object.defineProperty
劫持对象的setter
和 getter
来实现的。
/*
Vue
realState 为真正唯一的状态, 原来的 state 则是它的一个代理
*/
let realState = Object.create(null);
realState = Object.assign(realState,state);
Object.keys(state).forEach(key => {
Object.defineProperty(state,key,{
get(){
return realState[key]
},
set(newValue){
realState[key] = newValue;
vm = render(realState);
}
});
});
依赖这里先给出课上的一个题目,稍后再探讨在 Vue 的实际运用。
/*
实现一个 Dep 类,其中包含两个方法 depend() 和 notify()。
另外再实现一个函数 autorun(),接受一个函数 func, 会自动运行func。
如果在 func 中调用 depend() 方法则会订阅该函数, 调用 notify() 则会运行所有订阅的函数。
*/
let activeUpdate;
function autorun(update){
function updateWrapper(){ // 设置一个全局变量,这样可以在 depend() 中知道当前是否正在执行 update 函数。
activeUpdate = updateWrapper;
update();
activeUpdate = null;
}
updateWrapper();
}
window.Dep = class Dep{
constructor(){
this.stacks = new Set();
}
depend(){
if(activeUpdate){
this.stacks.add(activeUpdate);
}
}
notify(){
this.stacks.forEach(func => func());
}
}
观察发布者模式这一步我们想把前面两步结合起来,我们希望实现一个函数 observe
,传入一个对象,劫持它的 getter
和 setter
。这样每当我们调用 getter
时便收集它所有的依赖,然后在 setter
时调用 notify
触发所有的依赖。
function observe(state){
Object.keys(state).forEach(key => {
let value = state[key];
const dep = new Dep();
Object.defineProperty(state,key,{
get(){
dep.depend();
return value;
},
set(newValue){
value = newValue;
dep.notify();
}
});
});
}
特别申明:本文内容来源网络,版权归原作者所有,如有侵权请立即与我们联系(cy198701067573@163.com),我们将及时处理。
上一篇: 移动端适配奇技淫巧
下一篇: 我对JS延迟异步脚本的思考