初探Vue原理之view-model的数据动态双向绑定
Vue应用的是mvvm框架,view和model分离,然后通过vm双向数据绑定,`<!-- 模板 --><div id="app">{{msg}}</div><!-模型->// 原生对象即数据var data = {msg: 'hello!'}// 创建一个 ViewModel 实例var vm = new Vue({// 选择目标元素el:
·
Vue应用的是mvvm框架,view和model分离,然后通过vm双向数据绑定,`
<!-- 模板 -->
<div id="app">
{{msg}}
</div>
<!-模型->
// 原生对象即数据
var data = {
msg: 'hello!'
}
// 创建一个 ViewModel 实例
var vm = new Vue({
// 选择目标元素
el: '#app',
// 提供初始数据
data: data
})
然而一个动态数据的绑定,是怎么实现的呢,首先Vue利用es5的defineProperty方法里的get,set方法,进行数据的设置和获取。
Object.defineProperty(Vue.prototype, '$data', {
get () {
return this._data
},
set (newData) {
if (newData !== this._data) {
this._setData(newData)
}
} })
从这段源码可以看出设置数据时会调用setData方法,而setData的实现如下
Vue.prototype._setData = function (newData) {
newData = newData || {}
var oldData = this._data
this._data = newData
var keys, key, i
// unproxy keys not present in new data
keys = Object.keys(oldData)
i = keys.length
while (i--) {
key = keys[i]
if (!(key in newData)) {
this._unproxy(key)
}
}
// proxy keys not already proxied,
// and trigger change for changed values
keys = Object.keys(newData)
i = keys.length
while (i--) {
key = keys[i]
if (!hasOwn(this, key)) {
// new property
this._proxy(key)
}
}
oldData.__ob__.removeVm(this)
observe(newData, this)
this._digest()
}
这段代码的后三行可知首先移除旧的数据,然后调用observe(newData, this);
export function observe (value, vm) {
if (!value || typeof value !== 'object') {
return
}
var ob
if (
hasOwn(value, '__ob__') &&
value.__ob__ instanceof Observer
) {
ob = value.__ob__
} else if (
shouldConvert &&
(isArray(value) || isPlainObject(value)) &&
Object.isExtensible(value) &&
!value._isVue
) {
ob = new Observer(value)
}
if (ob && vm) {
ob.addVm(vm)
}
return ob
}
根据新的数据建立一个新的观察对象,这里提一下,vue用的是订阅模式,首先会把每个数据订阅一下,当数据变化时,会通知watcher重新计算值
最后一行代码this._digest()就是通知更新对象的值,把对象设置成newData,我理解的大概过程是这样的,大家看到有错误理解的欢迎给我指出来。这里提醒一下之前犯过的错误,例如:
<template>
<p>{{user.sex}}</p>
</template>
Data(){
User:{}
}
Ready(){
This.user={name:’smx’,age:12};
This.user.sex=’女’;
}
这将在视图里面无法显示,this.user是通过defineProperty里set方法设置进去的,所以在后面再设置属性的时候对象将不能跟踪到该属性
更多推荐
已为社区贡献2条内容
所有评论(0)