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

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

<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

<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),如下使用

<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双向绑定也是同理。

<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可以更简洁,性能也更好。

<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>

在这里插入图片描述

相关推荐

  1. Vue双向数据如何实现

    2024-04-29 09:24:05       29 阅读
  2. vue3组件数据双向

    2024-04-29 09:24:05       55 阅读
  3. vue双向数据v-model理解

    2024-04-29 09:24:05       37 阅读
  4. vue双向数据原理(v2、v3)

    2024-04-29 09:24:05       33 阅读
  5. Vue双向v-model详细介绍

    2024-04-29 09:24:05       40 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-29 09:24:05       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-29 09:24:05       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-29 09:24:05       87 阅读
  4. Python语言-面向对象

    2024-04-29 09:24:05       96 阅读

热门阅读

  1. FaceDiffuser 部署笔记

    2024-04-29 09:24:05       35 阅读
  2. Gateway

    Gateway

    2024-04-29 09:24:05      33 阅读
  3. Spring Cloud Gateway 原理

    2024-04-29 09:24:05       37 阅读
  4. 深入探究ES5与ES6的主要区别

    2024-04-29 09:24:05       35 阅读
  5. 迁移学习修改最后把一层类别数

    2024-04-29 09:24:05       33 阅读
  6. 智能家居如何融合人工智能技术

    2024-04-29 09:24:05       35 阅读
  7. Spring Cloud Gateway直接管理Vue.js的静态资源

    2024-04-29 09:24:05       32 阅读