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>

在这里插入图片描述

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值