聊一聊 Vue 双向数据绑定 v-model
这一天闲来无事的小新找到好朋友小兰约她一起去看电影,可是小兰说她正在学习Vue有一个问题一时间没有想明白,小新问她是什么问题,她说关于双向数据绑定是如何实现的呢?
双向数据绑定是什么样的呢?
我们经常会看到一个效果就是当在文本框输入内容时,页面上就会出现一模一样的内容,效果如下:
![](https://i-blog.csdnimg.cn/blog_migrate/105cc31d806bc8daf1942242bdbf7327.png)
如上图所示效果就是双向数据绑定,那么如何实现这个效果呢?
双向数据绑定通常会用到哪些地方呢,同时又需要依赖哪些前置条件呢?
我们一起探索一下吧。
实现简单的双向数据绑定:
要想实现双向数据绑定要从以下方面考虑:
- 页面和表单元素input绑定同一个变量。
- 当修改input值时我们要同时修改绑定的变量值。
- 当变量被改变时页面要同时更新内容。
<template>
<div class="hello">
<!-- 第一步 页面和input绑定了相同的变量text。-->
{{ text }}
<!-- 第二步 当input输入内容时会出发input事件,input事件处理函数会用新的内容更新text,text发生改变。-->
<input :value="text" @input="(e) => (text = e.target.value)" />
<!-- 第三步 当text值发生变化时,vue会更新绑定text变量地方的值。-->
</div>
</template>
<script>
export default {
data() {
return {
text: "",
};
},
};
</script>
双向数据绑定前置依赖什么?
通过上面的代码示例我们可以看到text
是被定义到data
中,如果不被定义到data
中那么还会有效果吗?答案是否,双双数据绑定前置条件就是所绑定的变量必须是响应式属性。更进一步说就是被Object.defineProperty
劫持处理过的属性。如果没有经过Object.defineProperty
那么当属性的值发生变化时,Vue是不知道的也不会更新依赖此属性地方的值。
用 v-model 实现双向数据绑定
我们不难看出双向数据绑定在开发已数据驱动视图的工作带来了很大的方便,但是我们不能每次都像实例一样书写代码,在维护上会有些不便,那么有什么更简单更方便的方式吗?我们可以通过 Vue 提供的指令v-model
来实现相同效果。
<template>
<div class="hello">
{{ text }}
<input v-moel="text" />
</div>
</template>
<script>
export default {
data() {
return {
text: "",
};
},
};
</script>
用v-model
写简洁了不少,本质上v-model
只不过是第一种写法的语法糖,v-model
在内部会根据不同的输入元素使用不同的property,并响应不同的事件:
- text 和 textarea 元素使用 value 和 input事件
- checkbox 和 radio 元素使用 checked 和 change事件
- select 元素使用 value 和 change事件
同时v-model
还可以用在自定义组件上,例如:自定义一个 Dialog 对话框,通过v-model
来显示和隐藏。
<!-- dialog.vue-->
<template>
<div class="dialog" v-if="showDialog">
<div>{{ title }}</div>
<div>{{ content }}</div>
<button @click="$emit('change',false)">关闭</button>
</div>
</template>
<script>
export default {
name: 'EDialog',
model: {
prop: 'showDialog',
event: 'change'
},
props: ['showDialog'],
data() {
return {
text: "dialog",
content: "Hello,World!"
};
},
};
</script>
<!-- parent.vue-->
<template>
<div>
<e-dialog v-model="dialog" />
<button @click="()=>dialog=true">点击我</button>
</div>
</template>
<script>
import EDialog from 'EDialog'
export default {
components:{
EDialog
},
data() {
return {
dialog: false
};
},
};
</script>
.sync
修饰符 实现同样效果
<!-- dialog.vue-->
<template>
<div class="dialog" v-if="showDialog">
<div>{{ title }}</div>
<div>{{ content }}</div>
<button @click="$emit('update:showDialog',false)">关闭</button>
</div>
</template>
<script>
export default {
name: 'EDialog',
props: ['showDialog'],
data() {
return {
text: "dialog",
content: "Hello,World!"
};
},
};
</script>
<!-- parent.vue-->
<template>
<div>
<e-dialog :showDialog.sync="dialog" />
<button @click="()=>dialog=true">点击我</button>
</div>
</template>
<script>
import EDialog from 'EDialog'
export default {
components:{
EDialog
},
data() {
return {
dialog: false
};
},
};
</script>
总结:
至此我们知道了如何实现双向数据绑定三种方式以及其意义,这些方法大大的提升了我们基于数据驱动视图开发的效率。那么双向数据绑定依赖的响应式就是我们接下来要了解的内容了。感谢,大家的阅读。小新也可以跟小兰快乐的去看电影啦。