Vue 的响应式原则与双向数据绑定

开发 前端
使用 Vue.js 久了,还是不明白响应式原理和双向数据绑定的区别?今天,我们就一起来学习一下,将解释它们的区别。

反应性原则

它是 Vue.js 的核心特性之一,一个数据驱动的视图,我们修改数据视图来响应更新,非常优雅。

Vue2.x 使用 Object.defineProperty() 实现,而 Vue3.x 使用 Proxy 实现。 我们先来看看2.x的实现。

Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function getter () {
return obj[key];
},
set: function setter (newVal) {
...
}
})

我们通过Object.defineProperty给对象obj添加属性,可以设置对象属性的getter和setter函数。  

之后,我们每通过点语法获取一个属性,就会执行这里的getter函数。 在这个函数中,我们会将调用这个属性的依赖收集到一个集合中; 当我们给属性赋值时,这个定义就会被触发。 setter函数,在辅助函数中,会通知集合中的依赖更新,让数据变化驱动视图变化。

3.x的核心思想和2.x一样,只是在数据劫持上使用了Proxy而不是Object.defineProperty,但是在处理数组和响应式处理新属性时Proxy比Object.defineProperty更方便 .

let nObj=new Proxy(obj,{
get: function (target, propKey, receiver) {
console.log(`getting ${propKey}!`);
return Reflect.get(target, propKey, receiver);
},
set: function (target, propKey, value, receiver) {
console.log(`setting ${propKey}!`);
return Reflect.set(target, propKey, value, receiver);
}
})

Vue响应式原理的实现细节相信大部分人已经很熟悉了,这里不再赘述。

双向数据绑定

双向数据绑定通常是指我们使用的 v-model 指令的实现。 它是 Vue 的一个特性,也可以说是输入事件和值的语法糖。 Vue 通过 v-model 指令为组件添加输入事件处理和值属性赋值。

<template>
<input v-model='localValue'/>
</template>

上面的组件等价于下面的代码。

<template>
<input @input='onInput' :value='localValue' />
<span>{{localValue}}</span>
</template>
<script>
export default{
data(){
return {
localValue:'',
}
},
methods:{
onInput(v){
this.localValue=v.target.value;
console.log(this.localValue)
}
}
}
</script>

因此,当我们修改输入框的值时,我们通过v-model绑定的值也会同步修改。 基于以上原理,我们可以轻松实现一个双向数据绑定组件。

v-model实践

首先,我们定义一个Vue组件:

<tempalte>
<div class="count" @click="addCount">click me {{value}}</div>
</template>
<script>
export default{
props:{
value:{
type:Number,
default:0
}
},
watch:{
value(v){
this.localvalue=v;
}
},
methods:{
addCount(){
this.localvalue++;
this.$emit('input',this.localvalue);
}
},
data(){
return{
localvalue:0
}
},
created(){
this.localvalue=this.value;
}
}
</script>

上面的组件指定我们在 props 中添加 value 属性,并在 value 更新时触发 input 事件。 在创建的 hook 和 watch 中对 localvalue 的赋值是将父组件的状态同步到子组件。

通过上面的组件定义,我们可以使用 v-model 指令对组件进行双向数据绑定。

<template>
<add-one v-model="count"></add-one>
<span>The parent component{{count}}</span>
</tempalte>
<script>
export default{
data() {
return {
count: 0,
};
},
methods: {
},
created(){
}
}
</script>

以下是实际效果。

当然,我们也可以不使用 value 和 input 事件的组合。 为了让组件的定义更加语义化,我们还可以自定义属性和事件,实现双向绑定。 我们可以在组件的模型选项中设置值和事件。 如下:

export default{
model:{
value:'count',
event:'change'
},
props:{
count:{
type:Number,
default:0
}
},
methods:{
addCount(){
this.localvalue++;
this.$emit('change',this.localvalue);
}
},
}

由上述组件定义。

<add-one v-model="count"></add-one>

相当于:

<template>
<add-one @change='onChange' :count='count'></add-one>
<span>{{count}}</span>
</template>
<script>
export default{
data(){
return {
count:0,
}
},
methods:{
onChange(v){
this.count=v;
console.log(this.count)
}
}
}
</script>

只是v-model指令帮我们做了上面的事件添加、属性绑定和状态同步操作。

最后

以上就是今天全部内容,谢谢你的阅读。如果你觉得有用,请记得点赞我,关注我,感谢感谢。

责任编辑:庞桂玉 来源: web前端开发
相关推荐

2022-09-02 10:34:23

数据Vue

2021-09-13 09:20:20

前端框架VUE

2021-02-19 23:07:02

Vue绑定组件

2021-04-02 11:24:22

Vue2.x双向绑定前端

2016-12-27 15:23:56

vue.js双向绑定操作

2017-10-27 22:03:35

javascrip

2017-08-30 17:10:43

前端JavascriptVue.js

2014-11-21 10:17:32

响应式WEB

2019-07-01 13:34:22

vue系统数据

2020-06-09 11:35:30

Vue 3响应式前端

2021-01-22 11:47:27

Vue.js响应式代码

2019-10-30 14:31:47

Vue 3.0数组响应

2022-04-17 09:18:11

响应式数据Vue.js

2023-11-27 07:47:14

2021-05-19 14:25:19

前端开发技术

2024-03-08 10:38:07

Vue响应式数据

2013-03-01 10:42:21

响应式Web

2021-07-14 13:12:51

2022-04-16 13:59:34

Vue.jsJavascript

2017-08-08 09:15:41

前端JavaScript页面渲染
点赞
收藏

51CTO技术栈公众号