美文网首页
双向绑定

双向绑定

作者: china_木木 | 来源:发表于2019-06-19 22:52 被阅读0次

数据响应式原理

  • vue实现数据响应式的原理就是利用了Object.defineProperty(),重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现。
  • 但是,vue3.0版本采用的是ES6的Proxy对象实现。

贴代码

<!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>Vue数据响应式原理</title>
</head>

<body>
    <script>
        //1.首先根据上图实现整体的一个架构(包括MVVM类或者VUE类,Watcher类)
        //2.然后
        //3.最后实现V-M, 当文本框输入文本的时候,由文本事件触发更新模型中的数据,同时也更新相对应的视图
        class Vue {
            constructor(options) {
                this.options = options
                this.$data = options.data //获取数据
                this.$el = document.querySelector(options.el) //#app 获取app对象

                this._directive = {}  //容器,存放订阅者的 ; 选择如下第二种,局部渲染
                //方式一:{订阅者1,订阅者2,订阅者3,订阅者4} | 全部渲染
                //方式二:{myText:[订阅者1,订阅者2],myBox:[订阅者3,订阅者4]} | 局部渲染

                this.Observer(this.$data) //数据
                this.Complite(this.$el) //元素
            }
            //劫持数据
            Observer(data) {
                for (let key in data) {
                    this._directive[key] = []
                    //此时要进行数据的劫持,需要修改data属性的get和set
                    let val = data[key]
                    let watch = this._directive[key] //return  array
                    Object.defineProperty(this.$data, key, {
                        get() {
                            return val;
                        },
                        set(newVal) {
                            if (newVal !== val) {
                                val = newVal
                                watch.forEach(element => {
                                    element.update()
                                });
                            }
                        }
                    })
                }
                console.log(this._directive)
            }
            //解析指令
            //找指令干嘛 ?? 依赖搜集! 好去订阅 data 里面的属性 -> 进行数据更新
            Complite(el) {
                let nodes = el.children //是app下的所有dom对象
                for (let i = 0; i < nodes.length; i++) {
                    let node = nodes[i]
                    // 递归查询所有dom元素 - 获取指令
                    if (node.children.length > 0) {
                        this.Complite(node)
                    }

                    if (node.hasAttribute('v-text')) {
                        let attrVal = node.getAttribute('v-text') //myText
                        //node 当前元素对象
                        //attrVal 当前元素对象 指令的值
                        this._directive[attrVal].push(new Watcher(node, this, attrVal, "innerHTML"))
                    }

                    if (node.hasAttribute('v-model')) {
                        let attrVal = node.getAttribute('v-model') //myText
                        //node 当前元素对象
                        //attrVal 当前元素对象 指令的值
                        this._directive[attrVal].push(new Watcher(node, this, attrVal, "value"))
                        let self = this
                        //箭头函数 this 就是指的vue 不需要重新引用
                        node.addEventListener("input", () => {
                            this.$data[attrVal] = node.value //给数据赋值
                        })
                    }
                }
                console.log(this._directive)
            }
        }

        //订阅者
        class Watcher {
            constructor(el, vm, exp, attr) {
                this.el = el //元素对象
                this.vm = vm
                this.exp = exp
                this.attr = attr
                this.update()
            }
            //主要功能 更新视图
            update() {
                this.el[this.attr] = this.vm.$data[this.exp]
                //更新元素 div 数据的操作
                //node.innerHtml = this.vue.$data['myText]
                //更新 input 数据的操作
                //node[value] = this.vue.$data['myText]
            }
        }
    </script>
    <div>
        <div id="app">
            <h1>数据响应式</h1>
            <div>
                <div v-text='myText'></div>
                <div v-text='myBox'></div>
                <input type="text" v-model="myText" />
                <input type="text" v-model="myBox" />
            </div>
        </div>
    </div>
    <script>
        const app = new Vue({
            el: "#app",
            data: {
                myText: "大吉大利 , 今晚吃鸡",
                myBox: "我是一个阿木木"
            }
        })
    </script>
</body>

</html>

相关文章

  • Vue 中的双向数据绑定

    双向绑定 单向数据流 双向绑定 or 单向数据流 Vue 是单向数据流,不是双向绑定 Vue 的双向绑定是语法糖 ...

  • vue2.0双向绑定的使用及简单实现

    v-model双向绑定用法input的双向绑定 chechbox(利用value值) v-model双向绑定简单实...

  • Vue之表单双向数据绑定和组件

    三、表单双向数据绑定和组件 目录:双向数据绑定、组件 1.双向数据绑定 1)什么是双向数据绑定Vue.js是一个M...

  • vue 面试汇总(更新中...)

    1.说说对双向绑定的理解 1.1、双向绑定的原理是什么 我们都知道Vue是数据双向绑定的框架,双向绑定由三个重要部...

  • 深入Vue响应式原理

    1.Vue的双向数据绑定 参考 vue的双向绑定原理及实现Vue双向绑定的实现原理Object.definepro...

  • [转] DataBinding 数据绑定

    数据绑定分为单项绑定和双向绑定两种。单向绑定上,数据的流向是单方面的,只能从代码流向 UI;双向绑定的数据是双向的...

  • Vue双向数据绑定v-model

    v-model 数据双向绑定用作双向数据绑定 一、组件内部双向数据绑定 1、在实例的data中,设置content...

  • 「1分钟--前端01」vue双向绑定

    目录 ⊙常见双向绑定的实现方法 ⊙基于数据劫持双向绑定的优点 ⊙基于Object.defineProperty双向...

  • 02Vue.js的数据绑定

    理解Vue的双向数据绑定 Vue有一个显著的地方就是它拥有双向数据绑定功能,那么何为双向数据绑定呢?双向是指:HT...

  • Vue入门(二)——数据绑定

    一、什么是双向数据绑定 双向数据绑定是Vue的核心功能之一。所谓双向数据绑定是指:HTML标签上的数据绑定到Vue...

网友评论

      本文标题:双向绑定

      本文链接:https://www.haomeiwen.com/subject/sutrqctx.html