-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Vue 进阶系列(一)之响应式原理及实现 #6
Labels
Comments
感谢分享 |
谢谢支持 |
下次出期关于vue生命周期函数的.谢谢 |
谢谢分享,有点没太看懂最后一大段代码autorun方法在哪里执行? |
作者只是没有写出来使用的代码,使用autorun注册多个需要更改dom的回调,类似于我这样: // test
var state = {
name: 'abc',
age: 20,
changeName() {
$('.v-modal h3').text(this.name);
},
changeAge() {
$('.v-modal p').text(this.age);
}
}
observe(state);
autorun(function() {
state.changeName();
})
autorun(function() {
state.changeAge();
})
setTimeout(()=> {
state.name = 'javascript';
state.age= 30;
}, 1200) <div class="v-modal">
<h3>heiheihei</h3>
<p>123</p>
</div> autorun的update参数执行的时候会调用getting方法,会注册一个set,当数据更改的时候会setting中的notify将所有注册的回调执行一次。 另外observe的setting中,将set赋值如果放在notify判断后的话会导致赋值失败的情况。 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Vue进阶系列汇总如下,欢迎阅读,欢迎加群讨论(文末)。
Vue 进阶系列(一)之响应式原理及实现
Vue 进阶系列(二)之插件原理及实现
什么是响应式Reactivity
Reactivity表示一个状态改变之后,如何动态改变整个系统,在实际项目应用场景中即数据如何动态改变Dom。
需求
现在有一个需求,有a和b两个变量,要求b一直是a的10倍,怎么做?
简单尝试1:
乍一看好像满足要求,但此时b的值是固定的,不管怎么修改a,b并不会跟着一起改变。也就是说b并没有和a保持数据上的同步。只有在a变化之后重新定义b的值,b才会变化。
简单尝试2:
将a和b的关系定义在函数内,那么在改变a之后执行这个函数,b的值就会改变。伪代码如下。
所以现在的问题就变成了如何实现
onAChanged
函数,当a改变之后自动执行onAChanged
,请看后续。结合view层
现在把a、b和view页面相结合,此时a对应于数据,b对应于页面。业务场景很简单,改变数据a之后就改变页面b。
现在建立数据a和页面b的关系,用函数包裹之后建立以下关系。
再次抽象之后如下所示。
view = render(state)
是所有的页面渲染的高级抽象。这里暂不考虑view = render(state)
的实现,因为需要涉及到DOM结构及其实现等一系列技术细节。这边需要的是onStateChanged
的实现。实现
实现方式是通过
Object.defineProperty
中的getter
和setter
方法。具体使用方法参考如下链接。需要注意的是
get
和set
函数是存取描述符,value
和writable
函数是数据描述符。描述符必须是这两种形式之一,但二者不能共存,不然会出现异常。实例1:实现
convert()
函数要求如下:
obj
作为参数Object.defineProperty
转换对象的所有属性示例:
在了解
Object.defineProperty
中getter
和setter
的使用方法之后,通过修改get
和set
函数就可以实现onAChanged
和onStateChanged
。实现:
实例2:实现
Dep
类要求如下:
Dep
类,包含两个方法:depend
和notify
autorun
函数,传入一个update
函数作为参数update
函数中调用dep.depend()
,显式依赖于Dep
实例dep.notify()
触发update
函数重新运行示例:
首先需要定义
autorun
函数,接收update
函数作为参数。因为调用autorun
时要在Dep
中注册订阅者,同时调用dep.notify()
时要重新执行update
函数,所以Dep
中必须持有update
引用,这里使用变量activeUpdate
表示包裹update的函数。实现代码如下。
wrappedUpdate
本质是一个闭包,update
函数内部可以获取到activeUpdate
变量,同理dep.depend()
内部也可以获取到activeUpdate
变量,所以Dep
的实现就很简单了。实现代码如下。
结合上面两部分就是完整实现。
实例3:实现响应式系统
要求如下:
convert()
重命名为观察者observe()
observe()
转换对象的属性使之响应式,对于每个转换后的属性,它会被分配一个Dep
实例,该实例跟踪订阅update
函数列表,并在调用setter
时触发它们重新运行autorun()
接收update
函数作为参数,并在update
函数订阅的属性发生变化时重新运行。示例:
结合实例1和实例2之后就可以实现上述要求,
observe
中修改obj
属性的同时分配Dep
的实例,并在get
中注册订阅者,在set
中通知改变。autorun
函数保存不变。实现如下:
Job Done!!!
交流
欢迎加我微信进一步交流或者找我内推,前行的路上,共勉!
The text was updated successfully, but these errors were encountered: