美文网首页
Vue 表单双向数据绑定原理简析

Vue 表单双向数据绑定原理简析

作者: 行走的蛋白质 | 来源:发表于2019-08-01 22:50 被阅读0次
  • v-model 指令实现双向数据绑定
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 
    v-model 指令实现双向数据绑定
    value 也是 v-model 的值
-->
<div id="app">
    <input type="text" v-model="text">
    <p>{{ text }}</p>
</div>
<script>
    let vm = new Vue({
        el: '#app',
        data: {
            text: 'protein'
        }
    })
</script>

vue实现数据双向绑定主要是:采用 数据劫持结合发布者-订阅者模式 的方式,通过 Object.defineProperty() 来劫持各个属性的 setter/getter,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

  • 原理简析 代码实现
    • 利用 Object.defineProperty() 对数据进行劫持,设置一个监听器 Observer,用来监听所有属性,如果属性上发上变化了,就需要告诉订阅者 Watcher 去更新数据,最后指令解析器 Compile 解析对应的指令,进而会执行对应的更新函数,从而更新视图,实现了双向绑定~
  • defineProperty 版
<body>

<div id="divEle"></div>
<input type="text" id="inputEle">

<script>
    
    let obj = { name: '' }
    let newO = JSON.parse(JSON.stringify(obj))
    
    Object.defineProperty(obj, 'name', {
        get: function() {
            return newO.name
        },
        set: function(v) {
            newO.name = v
            observer()
        }
    })
    
    function observer() {
        divEle.innerHTML = obj.name
        inputEle.value = obj.name
    }
    
    inputEle.oninput = function() {
        obj.name = this.value
    }
    setTimeout(_ => {
        obj.name = 'hello'
    }, 1000)
    
</script>

</body>
  • Proxy 版
<body>

<div id="divEle"></div>
<input type="text" id="inputEle">

<script>
    
    let obj = { name: '' }
    
    const handler = {
        get(target, prop) {
            return target[prop]
        },
        set(target, prop, value) {
            target[prop] = value
            observer()
        }
    }
    
    const p = new Proxy(obj, handler)
    
    function observer() {
        divEle.innerHTML = obj.name
        inputEle.value = obj.name
    }
    
    inputEle.oninput = function() {
        p.name = this.value
    }
    setTimeout(_ => {
        p.name = 'hello'
    }, 1000)
    
</script>

</body>
<div id="app">
    <input type="text" v-model="name">
    <input type="text" v-model="name">
    <input type="text" v-model="age">
    <p>{{name}}</p>
    <p>{{age}}</p>
</div>
<script>
    let data = { name: 'protein', age: 28 }

    // 1 --- 获取元素节点
    let app = document.getElementById('app')
    let inputs = app.getElementsByTagName('input')
    let nodeList = [...app.children].filter(item => item.nodeName != 'INPUT')
    let cloneList = nodeList.map(item => item.cloneNode(true))
    console.log(nodeList)

    // 2 --- 初始渲染
    for(let item of inputs) {
        if(item.getAttribute('v-model')) {
            item.value = data[item.getAttribute('v-model')]
        }
        // 4 --- 表单数据更新
        item.oninput = function() {
            data[this.getAttribute('v-model')] = this.value
        }
    }
    let reg = /\{\{(\w+)}}/
    nodeList.forEach(item => {
        if(reg.test(item.innerHTML)) {
            item.innerHTML = item.innerHTML.replace(reg, (...args) => data[args[1]])
        }
    })

    // 3 --- 数据更新
    Object.defineProperties(data, {
        name: {
            set(val) {
                console.log(this == data) // true
                for(let item of inputs) {
                    if(item.getAttribute('v-model') == 'name') {
                        item.value = val
                    }
                }
                cloneList.forEach((item, index) => {
                    nodeList[index].innerHTML = item.innerHTML.replace(/\{\{name}}/g, () => val)
                })
            }
        },
        age: {

        }
    })
    data.name = 'tomato'
</script>

相关文章

  • Vue 表单双向数据绑定原理简析

    v-model 指令实现双向数据绑定 vue实现数据双向绑定主要是:采用 数据劫持结合发布者-订阅者模式 的方式,...

  • 深入Vue响应式原理

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

  • vue 双向数据绑定

    Vue实现数据双向绑定的原理:Object.defineProperty()vue实现数据双向绑定主要是:采用数据...

  • 前端理论面试--VUE

    vue双向绑定的原理(详细链接) VUE实现双向数据绑定的原理就是利用了 Object.definePropert...

  • Vue实现数据双向绑定的原理

    Vue实现数据双向绑定的原理:Object.defineProperty() vue实现数据双向绑定主要是:采用数...

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

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

  • 【转】JavaScript的观察者模式(Vue双向绑定原理)

    关于Vue实现数据双向绑定的原理,请点击:Vue实现数据双向绑定的原理原文链接:JavaScript设计模式之观察...

  • vue面试知识点

    vue 数据双向绑定原理 vue实现数据双向绑定原理主要是:采用数据劫持结合发布订阅设计模式的方式,通过对data...

  • Vue 实例 一

    Vue实例基础一 数据的双向绑定 v-model 绑定表单的相应事件,和数据实现动态的双向绑定,需要在Vue实例中...

  • vue表单

    vue中表单主要通过v-model实现数据的双向绑定,实现原理主要通过javascript的object.defi...

网友评论

      本文标题:Vue 表单双向数据绑定原理简析

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