Vue3 v3.4之前如何实现组件中多个值的双向绑定?

Vue3 v3.4之前如何实现组件中多个值的双向绑定?

官方给的例子是关于el-input的,如下。但是@input不是所有组件标签都有的属性啊,有没有一种通用的办法呢?

language-html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script setup>
defineProps({

firstName: String,
lastName: String
})

defineEmits(['update:firstName', 'update:lastName'])
</script>

<template>
<input
type="text"
:value="firstName"
@input="$emit('update:firstName', $event.target.value)"
/>
<input
type="text"
:value="lastName"
@input="$emit('update:lastName', $event.target.value)"
/>
</template>

基础代码

以一个Dialog组件为例。我们自己写一个course-buy.vue

language-html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<template>
<el-dialog
v-model="localValue.dialogVisible"
title="Warning"
width="500"
align-center
>
<span>Open the dialog from the center from the screen</span>
<template #footer>
<div class="dialog-footer">
<el-button @click="localValue.dialogVisible = false">Cancel</el-button>
<el-button type="primary" @click="localValue.dialogVisible = false">
Confirm
</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import {
PropType} from "vue";

//对外变量
const props = defineProps({

dialogVisible: Object as PropType<boolean>,
courseId: Object as PropType<string | number>,
})
const emit = defineEmits(['update:dialogVisible','update:courseId'])
//本地变量
const localValue = reactive({

dialogVisible: props.dialogVisible,
courseId: props.courseId
})

</script>

外部在使用时(假设为base.vue),如下使用

language-html
1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<CourseBuy
v-model:dialog-visible="orderPayParams.dialogVisible"
v-model:course-id="orderPayParams.courseId"
/>
</template>
<script setup lang="ts">
const orderPayParams = reactive({

dialogVisible: false,
courseId: 1
});
</script>

上述代码,course-buy.vue中真正使用的变量是localValue本地变量,localValue的值来自base.vue
但是上述的基础代码,dialogVisiblecourseId的值只能从base.vue流向course-buy.vue
如何实现course-buy.vue本身修改localValue的值后,修改变化同步到base.vue呢?

1. watch

如果要让dialogVisible双向绑定,可以写两个watch互相监听并更新。要实现courseId双向绑定也是同理。

language-html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<script setup lang="ts">
import {
PropType} from "vue";

//对外变量
const props = defineProps({

dialogVisible: Object as PropType<boolean>,
courseId: Object as PropType<string | number>,
})
const emit = defineEmits(['update:dialogVisible','update:courseId'])
//本地变量
const localValue = reactive({

dialogVisible: props.dialogVisible,
courseId: props.courseId
})
//值双向绑定
watch(() => props.dialogVisible, (newValue) => {

localValue.dialogVisible = newValue;
});
watch(() => localValue.dialogVisible, (newValue) => {

emit('update:dialogVisible', newValue);
});
</script>

2. computed(推荐)

不过使用computed可以更简洁,性能也更好。

language-html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script setup lang="ts">
import {
PropType} from "vue";

//对外变量
const props = defineProps({

dialogVisible: Object as PropType<boolean>,
courseId: Object as PropType<string | number>,
})
const emit = defineEmits(['update:dialogVisible','update:courseId'])
//本地变量
const localValue = reactive({

dialogVisible: computed({

get: () => props.dialogVisible,
set: (value) => emit('update:dialogVisible', value)
}),
courseId: props.courseId
})
</script>

Vue3 v3.4之前如何实现组件中多个值的双向绑定?

https://xiamu-ssr.github.io/Hexo/2024/04/28/2024-H1/2024-04-28-20-55-44/

作者

Xiamu

发布于

2024-04-28

更新于

2024-08-11

许可协议

评论