vue3 双向绑定:如何在自定义组件中修改props定义的属性值,并更新父组件绑定的响应式变量值

1、自定义支持双向绑定的prop

在子组件中声明一个 count prop,通过触发 update:count 事件更新父组件值

子组件示例代码:

html 复制代码
<template>
    <div>
        <div>[子组件] count: {{ count }}</div>
        <button @click="onClick">+1</button>
    </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
    name: 'child-component',
    props: {
        count: {
            type: Number,
            default: 0
        }
    },
    emits: ['update:count'],
    setup(props, ctx) {
        const onClick = () => {
            ctx.emit('update:count', props.count + 1);
        }
        return {
            onClick
        };
    }
});
</script>

父组件示例代码:

html 复制代码
<template>
    <div>
        <div>[父组件] count: {{ count }}</div>
        <child-component :count="count" @update:count="count = $event"></child-component>
    </div>
</template>

<script lang="ts">
import ChildComponent from '@/components/child-component/child-component.vue';
import { defineComponent, ref } from 'vue';
export default defineComponent({
    components: { ChildComponent },
    setup() {
        return {
            count: ref<number>(0)
        };
    }
});
</script>

简化写法(语法糖),使用 v-model 双向数据绑定的指令

html 复制代码
<child-component v-model:count="count"></child-component>

2、子组件 prop 为 modelValue

在子组件中声明一个 modelValueprop,通过触发 update:modelValue 事件更新父组件值,父组件使用 v-model 、 v-model:modelValue 、 v-model:model-value 的写法都是支持的。

子组件示例代码:

TypeScript 复制代码
<script setup lang="ts">
  defineProps(['modelValue'])
</script>

<template>
  <el-input :modelValue="modelValue" @input="$emit('update:modelValue', $event)"/>
</template>

父组件示例代码:

TypeScript 复制代码
<script setup lang="ts">
import { ref } from 'vue'
import ChildComponent from './components/ChildComponent.vue'

const parentValue = ref('')
</script>

<template>
  <ChildComponent v-model="parentValue" />
</template>

其他支持写法:

TypeScript 复制代码
<ChildComponent v-model:modelValue="parentValue" />
<ChildComponent v-model:model-value="parentValue" />
<ChildComponent :modelValue="parentValue" @update:modelValue="parentValue = $event" />
<ChildComponent :model-value="parentValue" @update:model-value="parentValue = $event" />

3、子组件中也存在组件v-model 的值需与 prop 的值同步

定义一个可写的 computed 响应式变量,get直接返回传入子组件的 prop,set变更 prop 的值

TypeScript 复制代码
<script setup lang="ts">
  import { computed } from 'vue'

  const props = defineProps(['modelValue'])

  const emits = defineEmits(['update:modelValue'])

  const childValue = computed({
    get: () => props.modelValue,
    set: (val) => emits('update:modelValue', val)
  })
</script>

<template>
  <el-input v-model="childValue"/>
</template>

4、vue3.4+ 推荐使用 defineModel

写法更加简单,关于默认值、必填等选项配置可查阅文档

官方文档:https://cn.vuejs.org/api/sfc-script-setup.html#definemodel

子组件示例代码:

TypeScript 复制代码
<script setup lang="ts">
  const modelValue = defineModel()
</script>

<template>
  <el-input v-model="modelValue" />
</template>
相关推荐
sunbyte3 小时前
Tailwind CSS 初学者入门指南:项目集成,主要变更内容!
前端·css
可爱的秋秋啊3 小时前
vue3,element ui框架中为el-table表格实现自动滚动,并实现表头汇总数据
前端·vue.js·笔记·elementui
一夜枫林3 小时前
uniapp自定义拖拽排列
前端·javascript·uni-app
IT瘾君5 小时前
JavaWeb:Html&Css
前端·html
264玫瑰资源库6 小时前
问道数码兽 怀旧剧情回合手游源码搭建教程(反查重优化版)
java·开发语言·前端·游戏
喝拿铁写前端6 小时前
从圣经Babel到现代编译器:没开玩笑,普通程序员也能写出自己的编译器!
前端·架构·前端框架
HED6 小时前
VUE项目发版后用户访问的仍然是旧页面?原因和解决方案都在这啦!
前端·vue.js
拉不动的猪6 小时前
前端自做埋点,我们应该要注意的几个问题
前端·javascript·面试
王景程6 小时前
如何测试短信接口
java·服务器·前端
安冬的码畜日常7 小时前
【AI 加持下的 Python 编程实战 2_10】DIY 拓展:从扫雷小游戏开发再探问题分解与 AI 代码调试能力(中)
开发语言·前端·人工智能·ai·扫雷游戏·ai辅助编程·辅助编程