Vue 源码分析 (一)

准备知识

1、[].slice.call():将伪数组转换成真数组

  • 伪数组:length ,可下标获取 eg:$(“li”)
  • 验证 instanceof Array
  • Array.prototype.slice.call() 效率好点,原型链少查找一层

2、node.nodeType:得到节点类型,来做不同的方法处理

  • document / Element / Attr Text

3、Object.defineProperty(obj,propertyName,{}):给对象添加属性(指定描述符)

const obj = {
    firstName:'A',
    lastName:'B',
}

/**
 * configurable 是否重新定义
 * enumerable 是否可以枚举
 * value  初始值
 * writable 是否修改
 * get 动态获取当前值  回调函数
 * set 动态监听属性的变化 回调函数
 */
Object.defineProperty(obj,'fullName',{
    get(){
        return this.firstName + '_' + this.lastName
    },
    set(value){
        const names = value.split('_')
        this.firstName = names[0]
        this.lastName = names[1]
    }
})
console.log(obj.fullName) //A_B
obj.firstName = 'C'
obj.lastName = 'D'
console.log(obj.fullName) //C_D
obj.fullName = 'E_F'
console.log(obj.firstName,obj.lastName)// E F

Vue浏览器支持IE8以上,一部分原因就是这个属性IE8下不支持

4、Object.keys(obj):得到对象可枚举(enumerable)属性组成的数组

5、obj.hasOwnProperty(prop):判断prop是否是obj自身的属性,如果是原型继承的就是false

6、DocumentFragment:文档碎片(高效批量更新多个节点)内存中保存N个element的容器对象。如果更新framgnet中的某个element,界面不变,一次批量更新

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>测试</title>
</head>
<body>
    <ul id="fragment_test">
        <li>test1</li>
        <li>test2</li>
        <li>test3</li>
    </ul>

    <script>
        const ul = document.getElementById('fragment_test')
        //1.创建fragment
        const fragment =document.createDocumentFragment()
        //2.取出ul下面的子节点,保存到fragment
        let child;
        while(child=ul.firstChild){   //一个节点一个父亲
            fragment.appendChild(child) //先将child从ul中移除,调价到fragment
        }
        //3.更新fragment中所有li的文本  伪数组 包含文本节点和元素节点
        Array.prototype.slice.call(fragment.childNodes) .forEach(item => {
            if(item.nodeType===1){
                item.textContent = 'test4'
            }
        });   
        //4.将fragment放到ul中
        ul.appendChild(fragment)
    </script>
</body>
</html>

某大佬简易Vue源代码地址: https://github.com/DMQ/MVVM 以后文章代码讲解也是按照这个说的
自己新建一个html,把js文件导入,测试

    <script src="js/mvvm.js"></script>
    <script src="js/observer.js"></script>
    <script src="js/compile.js"></script>
    <script src="js/watcher.js"></script>
数据代理

1)数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)
2)vue 数据代理:通过vm对象来代理data对象中所有属性的操作

        const vm = new Vue({
            el:'#test', //原生  可以jquery[0]
            data:{
                name:'feifei'
            }
        }) 
        console.log(vm.name,vm) //feifei  vm代理对data数据的读操作
        vm.name = 'xiaoxiao' // vm代理对data数据的写操作
        console.log(vm._data.name,vm.name)  //xiaoxiao xiaoxiao

name(…)(invoke property getter)
在这里插入图片描述
3)好处:更方便的操作data中的数据
4)基本实现流程

  • a.通过object.defineProperty给vm添加与data对象属性对应的属性描述符
  • b.所有添加的属性都包含着getter/setter
  • c.getter/setter
function MVVM(options) {
    // 将配置对象保存到vm中 new()方法
    this.$options = options || {};
    // 将data对象保存到vm和变量data
    var data = this._data = this.$options.data;
    // 将vm保存到变量me
    var me = this;

    // 数据代理
    // 实现 vm.xxx -> vm._data.xxx
    Object.keys(data).forEach(function(key) {  // key:data中属性名    data:属性名集合
        me._proxyData(key);
    });
}

MVVM.prototype = {
    _proxyData: function(key, setter, getter) {    
        var me = this;
        setter = setter || 
        Object.defineProperty(me, key, {   //  核心
            configurable: false, // 不能重新定义
            enumerable: true,   //可枚举遍历

            // 当通过vm.xx读取属性值时调用时,从data中获取对应的属性值返回  代理读
            get: function proxyGetter() {
                return me._data[key];
            },
            // 当通过vm.xx=value时调用时,从data中保存对应的属性值  代理写操作
            set: function proxySetter(newVal) {
                me._data[key] = newVal;
            }
        });
    },
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值