375 数据双向绑定演示:一个 input + v-model,Object.defineProperty,数据双向绑定的原理简单实现

筅森魡賤 提交于 2020-03-14 15:30:26

5.1 一个 input + v-model

 v-model 指令 : 数据双向绑定的指令
 作用 : 把data中的msg值 和  input上的值 绑定到一起
 注意 : v-model只能用在 表单控件上 (input checkbox 等)
 > 可以在浏览器分别演示 V => M  和 M =>V
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <title>Document</title>
</head>

<body>
    <div id="app">
        <!-- V -->
        <!-- v-model  -->
        <!-- 
        作用 : 把`input的value值`  和 `data里的msg` 绑定到了一起, 只要一方发生变化,另外 一方会跟着改变 
       -->
        <input type="text" v-model="msg" />
    </div>
    <script src="./vue.js"></script>
    <script>
        const vm = new Vue({
            el: '#app',
            data: {
                // M
                msg: '这是测试信息'
            }
        })
    </script>
</body>

</html>


5.2 Object.defineProperty

内在-响应式原理

let obj = {}
let temp

obj.name = 'zhanhgsan'

// 参数1 : 要给哪个对象设置属性
// 参数2 : 给对象设置什么属性
// 参数3 : 属性的修饰符
Object.defineProperty(obj, 'name', {
  set: function(newVal) {
    console.log('赋值了', newVal)
  },
  get: function() {
    console.log('取值了')
    return temp
  }
})

06-双向数据绑定原理01.html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <title>Document</title>
</head>

<body>
    <script>
        /**
         *
         * 1. vue的数据双向绑定 是通过 `数据劫持` Object.defineProperty() 来实现的  ,
         *     Object.defineProperty()  是 es5 提出来的一个 无法 shim(兼容) 的特性 , 无法兼容ie8以下
         *
         * 2.  Object.defineProperty()  添加/修改属性
         *
         */

        let obj = {}
        let temp = ''

        // 参数1 : 把属性添加到哪个对象上去
        // 参数2 : 添加的属性 【注意,属性名要加引号,否则不会调用 set、get方法。】
        // 参数3 : 属性描述符 对象形式
        Object.defineProperty(obj, 'name', {
            // 赋值
            set(newVal) {
                console.log('调用了set : ', newVal)
                temp = newVal
            },
            // 获取
            get() {
                console.log('调用了get')
                return temp
            }
        })
    </script>
</body>

</html>


5.3 数据双向绑定的原理简单实现

通过数据劫持来实现的

  1. <input type="text" id="txt" />
  2. 演示 : V ==> M
//1. 拿到文本框
const txt = document.getElementById('txt')
//2. 时刻监听txt ,拿到最新的值
txt.oninput = function() {
  console.log(this.value)
  obj.name = this.value
}

//3. 数据模型
var obj = {}
let temp

Object.defineProperty(obj, 'name', {
  // 给属性赋值的时候会掉
  set: function(newVal) {
    console.log('调用了set', newVal)
    temp = newVal

    txt.value = newVal
  },
  get: function() {
    console.log('调用了get')
    return temp
  }
})
  1. V => M
//1. 获取 input的值,最新值
//2. 通过监听oninput 拿到最新值
//3. 把最新值赋值给 obj.name
//4. 就会掉了set方法,就会修改了数据
  1. M => V
//1. obj.name = 'xxx'
//2. 调用 set方法
//3. 把值赋值给input元素

07-数据 双向绑定的实现.html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <title>Document</title>
</head>

<body>
    <!-- V  -->
    <input type="text" id="txt" />

    <script>
        // M
        let obj = {}
        let temp = ''

        // V => M 【视图层到模型层的数据绑定】
        let ipt = document.querySelector('#txt')
        ipt.oninput = function() {
            // console.log(this.value)
            obj.name = this.value
        }

        // M  ==> V 【模型层到视图层的数据绑定】
        Object.defineProperty(obj, 'name', {
            set(newVal) {
                temp = newVal
                ipt.value = newVal
            },
            get() {
                return temp
            }
        })
    </script>
</body>

</html>

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!