组件之间的双向绑定
最近在学习electron+vue
仿有道云笔记markdown
区域的代码中,遇到父组件与子组件数据需要同步变化的问题。
(可以利用组件间的v-model
或者.sync
修饰符)故做此总结。
利用 v-model
通常子组件更新某个变量并需要告知父组件时,需要子组件$emit
触发事件,然后父组件$on
监听该事件再去改变值。可以利用v-model
的使用原理来使组件之间利用v-model
进行双向绑定。
父组件通过
v-model
绑定一个变量传给子组件子组件通过
props['value']
接收。注意是value
子组件通过
$emit('input',XX)
去改变父组件中v-model
绑定的变量。注意是input
事件
v-model 原理
Vue
根据元素决定如何监听和处理数据。对于input
元素,您可以这样使用v-model
:
<input v-model="email" />
v-model
翻译成这样:
<input :value="email" @input="(e) => (email = e.target.value)" />
v-model 实现方案
// 子组件
<template>
<input @input="handleInput" /> //
这个事件不一定是input事件,只要可以改变content值的事件就可以
</template>
<script>
export default {
name:'BasicInput',
prop: ['value'],
data () {
return {
content: this.value
}
},
methods: {
handleInput (e) {
this.$emit('input', this.content) // 这个事件名字一定得失input事件
}
}
}
</script>
// 父组件
<basic-input v-model="email"></basic-input>
实现方案如上。
定制 v-model 的 prop 和 event
因为有时候value
或者input
需要作其他的用处,这个时候就可以定制其他变量来做啦。
// 子组件
export default {
model: {
prop: "hidden",
event: "blur",
},
props: ["hidden"], //此处不能漏掉
methods: {
handleInput(val) {
this.$emit("blur", val);
},
},
};
// 父组件
<basic-input v-model="email" />
vue 自动将其转换为:
<basic-input :hidden="email" @bulr="(e) => (email = e.target.value)" />
v-model 与.sync 区别
v-model 本质
<!--v-model写法-->
<my-component type="text" v-model="value">
<!--展开语法糖后的写法-->
<my-component type="text"
:value="value"
@input="value = $event.target.value"
>
<!--
默认针对原生组件input事件,但是如果子组件定义了针对事件
model: {
prop: "value",
event: "update"
},
则编译为
-->
<my-component type="text"
:value="value"
@update="(val) => value = val"
>
.sync 本质
<!--语法糖.sync-->
<my-component :value.sync="value" />
<!--编译后的写法-->
<my-component
:value="msg"
@update:value="(val) => value = val"
>
总结:两者本质是一样的,并没有任何区别:
"监听一个触发事件"="(val) => value = val"
区别
- 只不过
v-model
默认对应的是input
或者textarea
等组件的input
事件,如果在子组件利用update
替换这个input
事件,其本质和.sync
修饰符一模一样。比较单一,不能有多个。
// 子组件可以用自定义事件,来替换v-model默认对应的原生input事件,只不过我们需要在子组件手动 $emit
model: {
prop: "value",
event: "update"
},
- 一个组件可以多个属性用
.sync
修饰符,可以同时”双向绑定多个prop
,而并不像v-model
那样,一个组件只能有一个。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 ZengXPang's blog!
评论