← 返回首页
Vue基础教程(四)
发表时间:2020-04-11 13:12:25
讲解Vue数据的单向绑定与双向绑定

1.双向绑定和单向绑定

双向数据绑定和单向数据绑定: - 使用 v-bind 进行单向绑定 - 使用 v-model 进行双向数据绑定

例如:

<!DOCTYPE html>
<html lang="zh">
<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>Document Title</title>
</head>

<body>
    <!-- id标识vue作用的范围 -->
    <!-- 如果要将模型数据绑定在html属性中,则使用 v-bind 指令
     此时title中显示的是模型数据
   -->
    <div id="app">
        <!-- v-bind:value只能进行单向的数据渲染 -->
        单向:<input type="text" v-bind:value="searchMap.keyWord">
        <!-- v-model 可以进行双向的数据绑定  -->
        双向:<input type="text" v-model="searchMap.keyWord">

        <p>您要查询的是:{{searchMap.keyWord}}</p>
    </div>
    <!-- 引入开发环境的vue.js版本,包含了有帮助的命令行警告 ,这样使用的也是最新版本-->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
       // 创建一个vue对象
       let vm = new Vue({
            el: '#app',//绑定vue作用的范围,el是element的简写。
            data: {//定义页面中显示的模型数据或者说为属性
               searchMap:{
                   keyWord:'牛牛编程'
               }
            }
        })
    </script>
</body>
</html>

测试运行:

我们发现通过vm.searchMap.keyWord='百度',属性的改变可以影响单向和双向input的值。 双向input值修改也会立刻影响vm.searchMap.keyWord属性和单向input值。而单向input的值修改不影响vm.searchMap.keyWord属性和双向input值。

2.数据双向绑定的实现原理分析

Vue实现数据双向绑定的原理:结合发布-订阅模式,通过ES5新增的Object.defineProperty()方法劫持各个属性的setter和getter,Observer监听数据的变动。

下面是双向绑定精简实现代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type='text' id='test'>
<span id='spa'></span>
<script>
    let obj = {};
    let val = obj.msg;
    Object.defineProperty(obj,'msg',{
        set:function(newVal){
            val = newVal;
            document.getElementById('test').value = newVal;
            document.getElementById('spa').innerHTML= newVal;
        },
        get:function(){
            return val;
        }
    });
    document.addEventListener('keyup',function(e){
        obj.msg = e.target.value
    })
</script>

</body>
</html>