用vue的双向绑定简单实现一个todo-list的示例代码

2020-06-14 06:23:57易采站长站整理

前言

最近在学习vue框架的基本原理,看了一些技术博客以及一些对vue源码的简单实现,对数据代理、数据劫持、模板解析、变异数组方法、双向绑定有了更深的理解。于是乎,尝试着去实践自己学到的知识,用vue的一些基本原理实现一个简单的todo-list,完成对深度复杂对象的双向绑定以及对数组的监听,加深了对vue基本原理的印象。

github地址:todo-list

学习链接

前排感谢以下文章,对我理解vue的基本原理有很大的帮助!

剖析vue实现原理,自己动手实现mvvm by DMQ 

对vue早期源码的理解 by 梁少峰

实现效果

数据代理

1.简单介绍数据代理

正常情况下,我们都会把数据写在data里面,如下面所示


var vm = new Vue({
el: '#app',
data: {
title: 'hello world'
}
methods: {
changeTitle: function () {
this.title = 'hello vue'
}
}
})
console.log(vm.title) // 'hello world' or 'hello vue'

如果没有数据代理,而我们又要修改data里面的title的话,methods里面的changeTitle只能这样修改成

this.data.title = 'hello vue'
, 下面的console也只能改成
console.log(vm.data.title),
数据代理就是这样的功能。

2. 实现原理

通过遍历data里面的属性,将每个属性通过object.defineProperty()设置getter和setter,将data里面的每个属性都复制到与data同级的对象里。

(对应上面的示例代码)

 

触发这里的getter将会触发data里面对应属性的getter,触发这里的setter将会触发data里面对应属性的setter,从而实现代理。实现代码如下:


var self = this; // this为vue实例, 即vm
Object.keys(this.data).forEach(function(key) {
Object.defineProperty(this, key, { // this.title, 即vm.title
enumerable: false,
configurable: true,
get: function getter () {
return self.data[key]; //触发对应data[key]的getter
},
set: function setter (newVal) {
self.data[key] = newVal; //触发对应data[key]的setter
}
});
}

对object.defineProperty不熟悉的小伙伴可以在MDN的文档(链接)学习一下

双向绑定

数据变动 —> 视图更新
视图更新(input、textarea) –> 数据变动

视图更新 --> 数据变动
这个方向的绑定比较简单,主要通过事件监听来改变数据,比如input可以监听input事件,一旦触发input事件就改变data。下面主要来理解一下