Vue ready knowledge and source code analysis of proxy data

Ready knowledge

1, []. Slice.call () / Array.prototype.slice.call () converts the dummy array true arrays

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul id="fragment_test">
        <li>test1</li>
        <li>test2</li>
        <li>test3</li>
    </ul>
    <script>      
        const lis = document.getElementsByTagName('li')
        console.log(lis instanceof Array, lis[1].innerHTML, lis.forEach)  //false 'test2' undefined
        const lis2 = Array.prototype.slice.call(lis)
        console.log(lis2 instanceof Array, lis2[1].innerHTML, lis2.forEach)  //true 'test2' function   
    </script>
</body>
</html>

2, node.nodeType node type to give

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="test">哈哈哈</div>
    <script>
        const elementNode = document.getElementById('test')
        const attrNode = elementNode.getAttributeNode('id')
        const textNode = elementNode.firstChild
        console.log(elementNode.nodeType, attrNode.nodeType, textNode.nodeType)  //1 2 3   
    </script>
</body>
</html>

3, Object.defineProperty (obj, propertyName, {}) adding attributes (designated descriptor) to the subject the ES5 syntax does not support IE8

        Attribute Descriptor:

  • Data Descriptor

            configurable: Can redefine
            enumerable: whether enumeration
            value: Initial value
            writable: whether the attribute value can be modified

  • Access Descriptor

            get: callback function calculated dynamically according to the current property values of other related properties
            set: callback function, monitoring changes in the current attribute values, attribute values other related updates

const obj = {
    firstName: 'A',
    lastName: 'B'
}
Object.defineProperty(obj, 'fullName', {
    configurable: false,
    enumerable: true,
    get () {
        return this.firstName + ' ' + this.lastName
    },
    set (value) {
        const names = value.split(' ')
        this.firstName = names[0]
        this.lastName = names[1]
    }
})

4, Object.keys (obj) to give the array itself may be enumerated attributes of

const names = Object.keys(obj)
console.log(names)

5, obj.hasOwnProperty (prop) determines whether the own attributes prop

console.log(obj.hasOwnProperty('fullname'), obj.hasOwnProperty('toString'))

6, DocumentFragment document fragments (efficient update multiple nodes)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="test">哈哈哈</div>
    <ul id="fragment_test">
        <li>test1</li>
        <li>test2</li>
        <li>test3</li>
    </ul>
    <script>
        const ul = document.getElementById('fragment_test')
        const fragment = document.createDocumentFragment()
        let child
        while(child=ul.firstChild){  // 一个节点只能有一个父亲
            fragment.appendChild(child)
        }
        Array.prototype.slice.call(fragment.childNodes).forEach(node => {
            if (node === 1) {  //  元素节点<li>
                node.textContent = 'xixixi'
            }
        })
        ul.appendChild(fragment)        
    </script>
</body>
</html>

Data Agent

  • Data Agent: an object through an operation of another proxy object attributes (read / write)
  • vue data agent: proxy data to all the properties of the object by operation of the object vm
  • Benefits: more convenient operation of the data DATA
  • The basic implementation process:
  1. By Object.defineProperty () to vm attribute descriptor corresponding to the attribute data added to the object
  2. Add all the properties contain getter / setter
  3. getter / setter to operate inside a corresponding data attribute data
function MVVM (options) {
    this.$options = options
    var data = this._data = this.$options.data
    var me = this

    // 实现vm.xxx -> vm._data.xxx
    Object.keys(data).forEach(function(key){
        me.proxy(key)
    })
}

MVVM.prototype = {
    _proxy: function(key) {
        var me = this
        Object.defineProperty(me, key, {
            configurable: false,
            enumerable: true,
            // 当通过vm.xxx读取属性值时可调用,从data中获取对应的属性值返回,代理读操作
            get: function proxyGetter () {
                return me._data[key]
            },
            // 当通过vm.xxx = value时,value被保存到data中对应的属性上,代理写操作
            set: function proxySetter (value) {
                me._data[key] = value
            }
        })
    }
}
发布了20 篇原创文章 · 获赞 3 · 访问量 877

Guess you like

Origin blog.csdn.net/qq_16049879/article/details/104659371