vue组件中实现双向绑定

背景

在一些项目中,需要用到组件数据的双向绑定,即父子组件共享变量,一方改动另一方联动。

补充 2019年07月09日

根据之前用的方法,在部分环境中使用失效,参考 浅析Vue自定义组件的v-model 用了另外一种方式实现。
虽然这样确实可以实现了,但是在一些原理上还是不太明白,有时间去看看源码吧。

SyncValue component 定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template>
<div>
<input type="text" :value="value" @input="handleChange">
</div>
</template>

<script>
export default {
props:['value'],
methods:{
handleChange(event) {
this.$emit('input', event.target.value);
}
}
}
</script>

组件调用方

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<template>
<div id="app">
<SyncValue v-model="model"></SyncValue>
</div>
</template>

<script>
import SyncValue from './components/SyncValue'

export default {
name: 'app',
components: {
SyncValue
},
data() {
return {
model: '123'
}
}
}
</script>

使用 model 来实现双向绑定

举例:

设计一个编辑器组件 editor,一般父组件调用时赋值给组件,当组件中内容变化时,父组件的变量也要变化。

参考 vue 自定义组件 v-model双向绑定、 父子组件同步通信的多种写法
得到解决办法。

我们使用文章的方案二,通过 v-model 来实现。

v-model

父组件

1
2
3
4
5
6
7
8
9
10
11
12
13
<div>
<editor v-model="content"></editor>
</div>

<script>
export default {
data() {
return {
content: '默认值'
}
}
}
</script>

edtior component

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div>
{{content}}
</div>

<script>
export default {
// 使用 model,定义好 prop 和 event 事件
model: {
prop: 'content',
event: 'change'
},
props: {
content: {
type: String,
default: '',
required: false
}
}

// 经过一系列处理
this.$emit('change', this.content)
}
</script>