<强>一、前言
强>
Vue有一核心就是数据驱动(数据驱动的),允许我们采用简洁的模板语法来声明式的将数据渲染进DOM,且数据与DOM是绑定在一起的,这样当我们改变Vue实例的数据时,对应的DOM元素也就会改变了。
如下:
& lt; !DOCTYPE html> & lt; head> & lt;元charset=皍tf - 8”比; & lt;/head> & lt; body> & lt; div id=安馐浴北? {{名称}} & lt;/div> & lt;脚本src=" https://unpkg.com/vue/dist/vue.min.js "祝辞& lt;/script> & lt; script> var vm=new Vue ({ 埃尔:“#测试”, 数据:{ 名称:“猴子” } }); & lt;/script> & lt;/body> & lt;/html>
当我们在chrome控制台,更改vm.name时,页面中的数据也随之改变,但我们并没有与DOM直接接触,效果如下:
好了,今儿的核心就是模拟上述演示中的数据驱动。
<强>二、模拟Vue之数据驱动
强>
通过粗浅地走读Vue的源码,发现达到这一效果的核心思路其实就是利用ES5的defineProperty方法,监听数据数据,如果数据改变,那么就对页面做相关操作。
有了大体思路,那么我们就开始一步一步实现一个简易版的Vue数据驱动吧,简称SimpleVue。
Vue实例的创建过程,如下:
var vm=new Vue ({ 埃尔:“#测试”, 数据:{ 名称:“猴子” } });
因此,我们也依瓢画葫芦,构建SimpleVue构造函数如下:
函数SimpleVue (obj) { 这一点。$ el=document.querySelector (obj.el); 这一点。选择美元=obj; 这一点。_data=https://www.yisu.com/zixun/Object.create(空);//入口 this.init (); obj=零; }; SimpleVue。原型={ 构造函数:SimpleVue, 初始化:函数(){//TODO } }; >之前接下来,我们在SimpleVue原型上编写一个watchData方法,通过利用ES5原生的defineProperty方法,监听数据中的属性,如果属性值改变,那么我们就进行相关的页面处理。
如下:
SimpleVue。原型={//监听数据属性 watchData:函数(){ var data=https://www.yisu.com/zixun/this。options.data美元//得到的数据对象 键=种(数据),//数据对象上全部的自身属性,返回数组=这; keys.forEach(函数(elem){//监听每个属性 Object.defineProperty (elem, { 可列举的:真的, 可配置:没错, 得到:函数(){ 返回that._data [elem]; }, 设置:函数(newVal) { 那_data [elem]=newVal; that.update();//数据变化,更新页面 } }); [elem]=数据(elem);//初次进入改变(elem),从而触发更新方法 }); } }; >之前好了,如果我们检测到数据变化了呢?
那么,我们就更新视图嘛。
但是,怎么更新呢?
简单的实现方式就是,在初次构建SimpleVue实例时,就将页面中的模板保存下来,每次实例数据一改变,就通过正则替换掉原始的模板,即双括号中的变量,如下:
SimpleVue。原型={//初始化SimpleVue实例时,就将原始模板保留 getTemplate:函数(){ 这一点。模板=l.innerHTML美元; },//数据改变更新视图 更新:函数(){ var=这个, 模板=that.template, reg=/(* & # 63;) \ {\ {(\ w *) \} \}/g, 结果="; 结果=模板。替换(reg,函数(rs, $ 1, $ 2) { var val=,(2美元)| |”; 返回$ 1 + val; }); el美元。innerHTML=结果; console.log(“更新”); } }; >之前好了,整合上述js代码,完整的SimpleVue如下:
函数SimpleVue (obj) { 这一点。$ el=document.querySelector (obj.el); 这一点。选择美元=obj; 这一点。_data=Object.create(空);//入口 this.init (); obj=零; }; SimpleVue。原型={ 构造函数:SimpleVue, 初始化:函数(){ this.getTemplate (); this.watchData (); },//初始化SimpleVue实例时,就将原始模板保留 getTemplate:函数(){ 这一点。模板=l.innerHTML美元; },//监听数据属性 watchData:函数(){ var data=ptions.data美元//得到的数据对象 键=种(数据),//数据对象上全部的自身属性,返回数组=这; keys.forEach(函数(elem){//监听每个属性 Object.defineProperty (elem, { 可列举的:真的, 可配置:没错, 得到:函数(){ 返回that._data [elem]; }, 设置:函数(newVal) { 那_data [elem]=newVal; that.update();//数据变化,更新页面 } }); [elem]=数据(elem); }); },//数据改变更新视图 更新:函数(){ var=这个, 模板=that.template, reg=/(* & # 63;) \ {\ {(\ w *) \} \}/g, 结果="; 结果=模板。替换(reg,函数(rs, $ 1, $ 2) { var val=,(2美元)| |”; 返回$ 1 + val; }); el美元。innerHTML=结果; console.log(“更新”); } };Vue数据驱动模拟实现1