博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
对vue源码的初步认识和理解
阅读量:5271 次
发布时间:2019-06-14

本文共 3888 字,大约阅读时间需要 12 分钟。

      根据vue的官网介绍,可以得知vue是一个mvvm框架,且是响应式的。为了更深入了理解其内涵,本人以及理解实现了一个简单的mvvm学习的demo。下面分享给大家,欢迎大家一起讨论。

一、mvvm至少包含的内容

  1. 指令集合,如:text、model等
  2. 数据模型,与视图交互的数据
  3. 组件的支持:也就是部分html代码的动态更新

二、我的实现

1. 变量的定义与watch的实现

var directives = {}; //指令集合var vNodes = new Array(); //解析的Dom集合var dataModel = {    name:"name",    title: "title"}; //数据Modelvar Watch = {    isInit: false,    watchs: new Array(),    run: function(newValue, expOrfn){         var self = this;        if(!self.isInit){            expOrfn.call(vModel);        }        this.watchs.map(function(data,index){            data.nodes.map(function(d,i){                if(self.isInit){                    d.directive.init(newValue, d, data); //绑定初始化值, 以及初始化一些事件                }else{                    d.directive.update(newValue, d, data); //只更新值,此时run的调用来值value-set                }            });        });                self.watchs = [];    },    push:function(watch){        this.watchs.push(watch);    }} //任务管理

说明:

  1. Watch的push方法,用于依赖的添加,然后run来执行所以依赖,执行完成后,需要清理当前依赖的集合。在vue中依赖的收集是在dep中完成的,而watch提供的任务管理(不知道理解是否正确)

2. 指令的定义

directives.text = {     init: function(value, vNode){        vNode.elm.textContent = value;    },    update: function(value, vNode){        vNode.elm.textContent = value;    }}//需要响应事件的怎么办directives.model ={     init: function(value, vNode, _watch){        vNode.elm.value = value; //判断自己发生的改变,不应该再改变自己         vNode.elm.addEventListener('keyup',function(evt){            vNode.model[_watch.key] = vNode.elm.value;        });     },    update:function(){    }   }

说明:

  1. 由于是demo学习示例,所以只定义了简单的text和model两个指定,text:用于数据的显示,而model用于input(输入框)的响应

3. vModel的生成

//转换vModel,暂支持一级var properties = Object.getOwnPropertyNames(dataModel);var vModel = {}, formSetting = false;for( var index in properties){     (function refreshData(_index){        var key = properties[_index];        var property = Object.getOwnPropertyDescriptor(dataModel, key);        var setter = property.set;        var getter = property.get;        var _val = property.value;        var _getter = function(){            var val = getter ? getter.call(vModel) : _val;            //收集依赖,与watch要分开            Watch.push({                key: key,                nodes: vNodes.filter(function(data,index){                    return data.modelKey == key ? true : false;                }),                getter: _getter            });            return val;        };        Object.defineProperty(vModel, key, {            configurable: true,            enumerable: true,            set: function(value){                if(setter){                    setter.call(vModel, value);                }                 //处理依赖                Watch.run(value, _getter);                //this.value = value;            },            get: _getter        })    })(index);}

说明:

  1. vModel是根据dataModel生成的,也就是自定义了每个属性的get和set方法,在es6中也可以用proxy实现(是否说对了)。
  2. 在属性set的时候,会先调用get方法来收集依赖。方便值改变后,能将所影响的内容都修改掉。

4. 解析dom为vNode

//解析vNodesvar app = document.getElementById('app');app.childNodes.forEach(function(data,index){    if(data.nodeType != 1) return;    var hv = data.getAttribute('data-hv');    var hvs = hv.split(',');    hvs.forEach(function(item,row){        var keyValue = item.split(':'); //vNode对象上一定要有model,这是方便vNode相应时候的找vModel        vNodes.push({            directive: directives[keyValue[0]],            modelKey: keyValue[1],            model: vModel,            elm: data        });    });});

说明:

  1. 这里说解析为vNode很是牵强,因为此只是收集了dom上data-hv指定的指令,并将对就的指令、元素、vModel等组成一个对象存储在vNodes中,以供vModel各属性的get方法收集依赖时引用。

5. 第一次初始化

//调用所有的get一次Watch.isInit = true;var _keys = Object.getOwnPropertyNames(vModel);_keys.map(function(key,data){    var data = vModel[key];    Watch.run(data); });Watch.isInit = false;

说明:

  1. 将初始化的vModel的值渲染到Dom上,这里是主动执行每个的get,然后运行watch.run方法。
  2. 此处设计和实现本人感觉与vue的思路不对,如有高人看见,麻烦提点与指引。

6. 被解析的dom

转载于:https://www.cnblogs.com/cqhaibin/p/7006923.html

你可能感兴趣的文章
CSS min-height 属性
查看>>
模板设计模式的应用
查看>>
实训第五天
查看>>
平台维护流程
查看>>
2012暑期川西旅游之总结
查看>>
Linux发行版的排行
查看>>
12010 解密QQ号(队列)
查看>>
2014年辛星完全解读Javascript第一节
查看>>
装配SpringBean(一)--依赖注入
查看>>
daydayup2 codeforces143C
查看>>
ANT打包J2EE项目war包
查看>>
UESTC-我要长高 DP优化
查看>>
java选择文件时提供图像缩略图[转]
查看>>
方维分享系统二次开发, 给评论、主题、回复、活动 加审核的功能
查看>>
Matlab parfor-loop并行运算
查看>>
string与stringbuilder的区别
查看>>
2012-01-12 16:01 hibernate注解以及简单实例
查看>>
iOS8统一的系统提示控件——UIAlertController
查看>>
PAT甲级——1101 Quick Sort (快速排序)
查看>>
python创建进程的两种方式
查看>>