前言
最近在学习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。下面主要来理解一下










