初探Vue原理之view-model的数据动态双向绑定
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方法设置进去的,所以在后面再设置属性的时候对象将不能跟踪到该属性
上一篇:
IDEA上Java项目控制台中文乱码