• 简单实现vue双向数据绑定


    Vue 的响应式原理是核心是通过 ES5 的保护对象的 Object.defindeProperty 中的访问器属性中的 get 和 set 方法,data 中声明的属性都被添加了访问器属性,当读取 data 中的数据时自动调用 get 方法,当修改 data 中的数据时,自动调用 set 方法,检测到数据的变化,会通知观察者 Wacher,观察者 Wacher自动触发重新render 当前组件(子组件不会重新渲染),生成新的虚拟 DOM 树,Vue 框架会遍历并对比新虚拟 DOM 树和旧虚拟 DOM 树中每个节点的差别,并记录下来,最后,加载操作,将所有记录的不同点,局部修改到真实 DOM 树上。

     虚拟DOM (Virtaul DOM): 用 js 对象模拟的,保存当前视图内所有 DOM 节点对象基本描述属性和节点间关系的树结构。用 js 对象,描述每个节点,及其父子关系,形成虚拟 DOM 对象树结构。

    简单实现vue双向数据绑定:

    <!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>
        <input id="inp" type="text">
        <span id="spanEle"></span>
    
    </body>
    <script>
        let inpEle = document.getElementById('inp');
        let spanEle = document.getElementById('spanEle');
    
        inpEle.addEventListener('input', function () {
            data.name = inpEle.value;
        })
    
        function render() {
            spanEle.innerHTML = JSON.stringify(data);
        }
        let data = {
            name: '请输入你的姓名',
            location: { x: 100, y: 100 }
        }
        inpEle.value = data.name;
        observe(data)
        function observe(obj) { // 数据劫持
            // 判断类型
            if (!obj || typeof obj !== 'object') {
                return
            }
            Object.keys(obj).forEach(key => {
                defineReactive(obj, key, obj[key])
            })
            function defineReactive(obj, key, value) {
                // 递归子属性
                observe(value)
                Object.defineProperty(obj, key, {
                    enumerable: true, //可枚举(可以遍历)
                    configurable: true, //可配置(比如可以删除)
                    get: function reactiveGetter() {
                        console.log('get:', value) // 监听
                        return value
                    },
                    set: function reactiveSetter(newVal) {
                        observe(newVal) //如果赋值是一个对象,也要递归子属性
                        if (newVal !== value) {
                            value = newVal
                            render()
                            console.log('set:', newVal) // 监听
    
                        }
                    }
                })
            }
        }
    
        setTimeout(() => {
            data.location = {
                x: { xx: { xxx: 2020 } },
                y: 2020
            }
            console.log(data.name);
        }, 1000)
    
        setTimeout(() => {
            data.location.x.xx.xxx = 0823;
        }, 4000)
    
    </script>
    
    </html>
  • 相关阅读:
    curl crt
    test with nmap
    C#查询XML解决“需要命名空间管理器”问题
    Dapper实用教程
    javascript 计算两个日期的差值
    Glib学习笔记(二)
    安装osquery笔记
    Golang多线程简单斗地主
    PHP扩展开发之Zephir
    zabbix 安装记录
  • 原文地址:https://www.cnblogs.com/anu0823/p/12739415.html
Copyright © 2020-2023  润新知