实现一个简单的类 Vue 框架(二) —— 数据的绑定之修改可监听的数据绑定方法
2019-05-17 19:32
627 查看
Vue是MVVM框架,也就是M(数据)的变化能够驱动V(模板)的变化,所以数据修改可响应的实现是一个关键点。实现数据变化可响应的方法很多,事件驱动,广播,订阅等方法,而Vue使用的是js的原生API Object.defineProperty。这种实现方法的优点是:实现简单。缺点是:只能兼容到IE9以上。
针对上一篇文章:https://blog.csdn.net/SunShinessx/article/details/90293626,本篇用Object.defineProperty实现修改可监听的数据驱动:
[code]/* 修改可监听的数据绑定 */ function Sue(options) { initData(this,options) if (typeof options.ready === 'function') { options.ready.call(this) } } function initData (vm,options) { var data = options.data; data = typeof data === 'function' ? data() : data || {}; for (let key in data) { if (data.hasOwnProperty(key)) { let value = data[key] Object.defineProperty(vm,key,{ enumerable: true, configurable: true, get() { console.log(`get ${key}`); return value }, set(newVal) { if(value !== newVal){ value = newVal console.log(`set ${key}`); } } }) } } } var sue = new Sue({ data(){ return { name:'ssx', age:18 } }, ready(){ console.log("name",this.name); console.log("age",this.age); this.name = 'lili' this.age = 19 } }) console.log(sue.name); console.log(sue.age);
存在的问题:如果data是一个对象,对对象的修改将不能监听到。
解决方法:遍历data对象,然后对data对象的属性也做 Object.defineProperty处理。
[code]/* 修改可监听的数据绑定---data的属性是对象 */ function Sue(options) { initData(this,options) if (typeof options.ready === 'function') { options.ready.call(this) } } function initData (vm,options) { var data = options.data; data = typeof data === 'function' ? data() : data || {}; _each(vm,data) } function _each(obj,sourceObj) { bindData(obj,sourceObj) for (let key in sourceObj) { if(typeof sourceObj[key] == 'object'){ bindData(sourceObj[key],sourceObj[key]) } } } function bindData(obj,sourceObj) { for (let key in sourceObj) { if (sourceObj.hasOwnProperty(key)) { let value = sourceObj[key] Object.defineProperty(obj,key,{ enumerable: true, configurable: true, get() { console.log(`get ${key}`); return value }, set(newVal) { if(value !== newVal){ value = newVal console.log(`set ${key}`); } } }) } } } var sue = new Sue({ data(){ return { info:{ name:'ssx', age:18 } } }, ready(){ console.log("name",this.info.name); console.log("age",this.info.age); this.info.name = 'lili' this.info.age = 19 } })
存在问题:如果info的属性在开发过程中新增加了,是不能检测到的。
解决方法:vue.$set方法就是解决这个问的。简化后的$set方法可以这样实现:
[code]/* 修改可监听的数据绑定---data对象属性随意增加也可以监听到 */ function Sue(options) { this.initData(this,options) if (typeof options.ready === 'function') { options.ready.call(this) } } Sue.prototype = { constructor:Sue, $set(obj,key,value){ Object.defineProperty(obj,key,{ enumerable: true, configurable: true, get() { console.log(`get ${key}`); return value }, set(newVal) { if(value !== newVal){ value = newVal console.log(`set ${key}`); } } }) }, initData (vm,options) { var data = options.data; data = typeof data === 'function' ? data() : data || {}; this._each(vm,data) }, _each(obj,sourceObj) { this.bindData(obj,sourceObj) for (let key in sourceObj) { if(typeof sourceObj[key] == 'object'){ this.bindData(sourceObj[key],sourceObj[key]) } } }, bindData(obj,sourceObj) { for (let key in sourceObj) { if (sourceObj.hasOwnProperty(key)) { let value = sourceObj[key] Object.defineProperty(obj,key,{ enumerable: true, configurable: true, get() { console.log(`get ${key}`); return value }, set(newVal) { if(value !== newVal){ value = newVal console.log(`set ${key}`); } } }) } } } } var sue = new Sue({ data(){ return { info:{ name:'ssx', age:18 } } }, ready(){ console.log("name",this.info.name); console.log("age",this.info.age); this.info.name = 'lili' this.info.age = 19 } }) sue.$set(sue.info,'school','福大') console.log("school",sue.info.school)
相关文章推荐
- VUE+SSM 以VUE做项目前端,SSM做后端框架,难点在于数据的传输处理,下面我记录一下一个简单的登录退出功能的实现,如果有缺陷还请大佬指出,个人菜鸟 一个,正在学习当中,以此记录一下自己的学习
- Vue数据双向绑定原理及简单实现方法
- 【学习笔记】剖析MVVM框架,简单实现Vue数据双向绑定
- JavaScript实现简单的双向数据绑定(Ember、Angular、Vue)
- RoboBinding:一个实现了数据绑定 Presentation Model(MVVM) 模式的Android开源框架
- Yii框架批量插入数据扩展类的简单实现方法
- vue动态数据绑定1--如何监听一个对象的变化
- C#数据绑定(DataBinding)简单实现方法
- 简单实现Vue数据双向绑定
- Laravel框架实现修改登录和注册接口数据返回格式的方法
- MAC Tree 实现的方法(NSOutlineView) 2 (实现了简单的选择和动态修改不同的数据)
- 浅析VUE双向绑定原理,实现数据监听并通知订阅者
- Vue实现双向绑定的原理以及响应式数据的方法
- vue 双向数据绑定的实现学习之监听器的实现方法
- Vue组件内部实现一个双向数据绑定的实例代码
- 简单完整的代码,通过这个代码你将对RSA加密算法在Java中的实现方法有一个初步的了解,这个类,你可以直接使用,水平高的,就自己修改完善下代码。
- 利用 JavaScript 数据绑定实现一个简单的 MVVM 库
- JavaScript数据绑定实现一个简单的 MVVM 库
- 用vue的双向绑定简单实现一个todo-list的示例代码
- 在一个程序中需要用到全局变量(在多个class之间共享数据),请问如何定义具有这种功能的变量?或者是否有其他的方法解决多个class之间的数据共享(尽量简单实现)。 首先应该明确 Java中没有全局变