-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # 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判断后的话会导致赋值失败的情况。 |
# for free
to join this conversation on GitHub.
Already have an account?
# 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: