在vue开发中,通常会对一个自定义的组件进行封装,并实现v-model双向绑定功能

在 Vue 2 中,通常这样实现

父组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template>
<Child v-model="number"></Child>
</template>

<script>
export default {
data() {
return {
number: 0,
};
},
components: {
Child: () => import("./Child.vue"),
},
};
</script>

子组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template>
<button @click="handleClick">{{ value }}</button>
</template>

<script>
export default {
props: {
value: Number,
},
methods: {
handleClick() {
// 通过emit一个input事件出去,实现 v-model
this.$emit("input", this.value + 1);
},
},
};
</script>

在 vue 3 中,通过这样实现

父组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<template>
<Child v-model="number"></Child>
</template>

<script lang="ts">
import { defineComponent, ref } from "vue";
export default defineComponent({
setup() {
const number = ref(0);
return {
number,
};
},
});
</script>

子组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template>
<button @click="handleClick">{{ value }}</button>
</template>
<script lang="ts">
import { defineComponent } from "vue";

export default defineComponent({
props: {
// 更换成了 modelValue
modelValue: Number,
},
setup(props, { emit }) {
// 关闭弹出层
const handleClick = () => emit("update:modelValue", props.modelValue + 1);
return { handleClick };
},
});
</script>