首先聊一个概念什么叫数据做绑定呢
概念:
<a>标签有一个属性href,href的值得看粉红色这个表达式的结果,就比如吧这个粉红色表达式的值是1 ,那么href这个属性的值也就是1,这样的话红色的属性与粉红色的表达式之间就有了一个绑定的关系。
绑定又分为单向数据绑定与双向数据绑定,上示例中是单向数据绑定,下面我们再来看一个单向数据绑定的例子:
<div id="#root">
<h2 v-bind:x="name">你好啊</h2>
</div>
<script>
new Vue({
el: "#root",
data: {
name: '尚硅谷'
}
})
</script>
效果图:
单向绑定(v-bind):数据只能从data流向(控制)页面
双向数据绑定:
<div id="root">
双向数据绑定:<input type="text" v-model:value="name" >
</div>
</body>
<script >
new Vue({
el: "#root",
data: {
name: '尚硅谷'
}
})
</script>
效果图:
双向数据绑定:
双向绑定(v-model):数据不仅能从data中流向(控制)页面,还可以从页面流向(控制)data
数据绑定备注:
- 双向绑定一般应用在表单类元素上(如:input,select).(输入类元素,非输入类元素也用不了)
- v-model:value还可以简写为v-model因为v-model默认收集的就是value
- v-bind:value可以简写为:value(即省略v-bind)
那么又什么是数据代理呢?
1.数据代理:通过一个对象代理另外一个对象(在前一个对象内部)中属性的操作(读写)
2.vue数据代理:通过vm对象来代理data对象中所有属性的操作
3.好处更方便的操作data中的数据
看一下数据代理基本概念:
<script type="text/javascript">
/用一段代码解释一下什么是数据代理, 将obj2数据交给obj代理/
let obj = {x;100};
let obj2 = {y:200};
Object.defineProperty(obj2,'x',{
get(){ return obj.x },
set(value){ obj.x = value }
})
</script>
ps:验证数据代理:
下面就写了一段代码来验证vue
中存在的数据代理是否成立,即图中setter
与getter
两条线,如下图中💙蓝色和💗红色的线
<body>
<div id="root">
<h2>学校名称: {{name}}</h2>
<h2>学校地址: {{address}}</h2>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false; /阻止vue在启动时生成生产提示/
const vm = new Vue({
el:'#root',
data:{ /vm._data就是这个里面的data,它做了一个数据劫持/
name:'尚硅谷',
address:'上海'
}
})
console.log(vm,"打印vm为了便于观察");
/执行结果为Vue实例, 其中data中每个数据(如name,address)都有自己的getter与setter/
</script>
下面的代码验证了vm._data
就是这个里面的data
,而在vm._data
内部做了一个数据劫持。
<body>
<div id="root">
<h2>学校名称: {{name}}</h2> /所以如果vue中没做数据代理{{name}}就得写成{{_data.name}}/
<h2>学校地址: {{address}}</h2>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false; /阻止vue在启动时生成生产提示/
let data = {
name:'尚硅谷',
address:'上海'
}
const vm = new Vue({
el:'#root',
data
})
console.log(vm._data === data);
/执行结果为true, 所以vm._data就是data, 蓝色的线就可以验证了/
</script>
因为当我们修改data
中的值,页面上面的显示值同步修改,这就验证了红色线可以成立
ps:了解数据代理的实际开发中意义:
我们先来看看不用数据代理改怎么实现数据的绑定及各种(data)数据变化来实现页面元素的变化,
基本流程:
先看代码:
<div id="root">
<h2>学校名称{{_data.name}}</h2>
<h2>学校:{{_data.address}}</h2>
</div>
<script>
Vue.config.productionTip = false
new Vue({
el: '#root',
data: {
name: '尚硅谷',
address: '宏福科技园'
})
</script>
效果图:
注意代码中插值语法写的是:{{_data.name}},因为vm_.data是vm收集vm实例中的data属性数据(mvvm模型中model传过来的),data对象中的数据会被vm收到,收到之后肯定得存起来不然怎么用,数据都没了,哪来谈数据变化影响页面,vm把这个数据存在了vm自身vm_data这个属性中,所以插值语法可以写成{{_data.name}}
如果vue
中没做数据代理{{name}}
就得写成{{_data.name}}
,令编码更加方便,这就是数据代理在Vue
中的实际应用意义
即是这个图:
再次说明下呗:实际应用意义
vue实例对象上并一开始没有mvvm模型中的data中的数据,他收到之后放在vue实例对象的某个属性中即是vm._data中,
vm_.data是vm收集model传过来在属性数据(经过数据代理,
data中所有的属性,最后都出现在了vm身上(vue实例),在vue模板中都可以直接用。
通过vm对象来代理data中所有属性的操作
数据代理的实现流程:
❶当我们声明vue实例对象之后,即vm;
❷vm中会生成各种配置对象options,其中options包含了_data;
❸由于底层代码的支持会自动给_data中每个数据,在_data的外部(即同级)添加对应新的元素(即数据代理),如上图中的name、address,同时每个name、address中都会有setter、getter函数。
小结:
基本原理: ❶通过Object.defineProperty()把data对象中所有属性添加到vm上; ❷为每一个添加到vm上的属性,都指定一个getter/setter; ❸在getter/setter内部去操作(读/写)data中对应的属性。