【Vue3】使用v-model实现父子组件通信(常用在组件封装规范中)

历史小剧场

历史告诉我们,痞子就算混一辈子,也还是痞子,滑头,最后只能滑自己。长得帅,不能当饭吃。

成大器者的唯一要诀,是能吃亏。

吃亏就是占便宜,原先我不信,后来我信了,相当靠谱。----《明朝那些事儿》

概述

v-mode实现父子组件数据同步原理主要分为:

  • 父组件添加modelValue绑定数据且传递到子组件,然后绑定@update:modelValue事件接收子组件传过来的值
  • 子组件内部使用defineProps来接收父组件modelValue传过来的值,使用defineEmits自定义事件修改值然后触发父组件@update绑定的事件

同步单个数据

父组件

js 复制代码
<!--  -->
<template>
    <div>

        <!-- v-model用在HTML上 -->
        <!-- <input type="text" v-model="username"> -->
        <!-- <input type="text" :value="username" @input="username = (<HTMLInputElement>$event.target)!.value" /> -->

        <h4>账号: {{ username }}</h4>
        <h4>密码: {{ pwd }}</h4>
        <!-- v-model用在自定义组件上 -->
        <!-- <XinchaoInput v-model:username="username" v-model:pwd="pwd" /> -->
        <XinchaoInput 
        :username="username"
        @update:username="username = $event" />
    </div>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue';
import XinchaoInput from './XinchaoInput.vue';


const username = ref<string>("张三")
const pwd = ref<string>("123131")
watch(username, (oldValue, newValue) => {
    console.log(newValue)
})
</script>

<style lang="scss" scoped>

</style>

子组件

js 复制代码
<!--  -->
<template>
    <div>
        <input type="text"
        :value="username"
        @input="emit('update:username', (<HTMLInputElement>$event.target)!.value)" />
        <!-- <br>
        <input type="text"
        :value="pwd"
        @input="emit('update:pwd', (<HTMLInputElement>$event.target)!.value)" /> -->
    </div>
</template>

<script setup lang="ts">
defineProps(['username', 'pwd'])
const emit = defineEmits(['update:username', 'update:pwd'])

</script>

<style lang="scss" scoped>
input {
    border: 2px solid #ccc;
    border-radius: 5px;
    padding: 2px;
    background-color: darkcyan;
    color: white;
}
</style>

同步多个数据

父组件

js 复制代码
<!--  -->
<template>
    <div>

        <!-- v-model用在HTML上 -->
        <!-- <input type="text" v-model="username"> -->
        <!-- <input type="text" :value="username" @input="username = (<HTMLInputElement>$event.target)!.value" /> -->

        <h4>账号: {{ username }}</h4>
        <h4>密码: {{ pwd }}</h4>
        <!-- v-model用在自定义组件上 -->
        <XinchaoInput v-model:username="username" v-model:pwd="pwd" />
        <!-- <XinchaoInput 
        :username="username"
        @update:username="username = $event" /> -->
    </div>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue';
import XinchaoInput from './XinchaoInput.vue';


const username = ref<string>("张三")
const pwd = ref<string>("123131")
watch(username, (oldValue, newValue) => {
    console.log(newValue)
})
</script>

<style lang="scss" scoped>

</style>

子组件

js 复制代码
<!--  -->
<template>
    <div>
        <input type="text"
        :value="username"
        @input="emit('update:username', (<HTMLInputElement>$event.target)!.value)" />
        <br>
        <input type="text"
        :value="pwd"
        @input="emit('update:pwd', (<HTMLInputElement>$event.target)!.value)" />
    </div>
</template>

<script setup lang="ts">
defineProps(['username', 'pwd'])
const emit = defineEmits(['update:username', 'update:pwd'])

</script>

<style lang="scss" scoped>
input {
    border: 2px solid #ccc;
    border-radius: 5px;
    padding: 2px;
    background-color: darkcyan;
    color: white;
}
</style>
相关推荐
突然暴富的我14 分钟前
html三级菜单
前端·html
性野喜悲44 分钟前
vue通过后台返回的数字显示不同的文字内容,多个内容用、隔开
前端·javascript·vue.js
袁亦袁1 小时前
通过属性透传,iview Table组件实现自适应高度
javascript·vue.js·iview
武汉前端开发蓝风1 小时前
前端Debugger时复制的JS对象字符转JSON对象
前端·javascript·json·debugger
爱编程的鱼1 小时前
HTML如何在图片上添加文字
前端·javascript·html
顶顶年华正版软件官方2 小时前
关键帧功能怎么使用 关键帧控制视频特效怎么用 会声会影视频剪辑软件教程
前端·javascript·音视频·学习方法·关键帧·会声会影教程·视频剪辑软件
来之梦2 小时前
uniapp自定义富文本现实组件(支持查看和收起)
前端·javascript·uni-app
森叶2 小时前
Electron开发 - 如何在主进程Main中让node-fetch使用系统代理
前端·javascript·electron
睿麒2 小时前
前端八股文 说一说样式优先级的规则是什么?
前端
甜兒.2 小时前
禹神electron学习~
javascript·学习·electron