【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>
相关推荐
狂奔solar3 分钟前
分享个好玩的,在k8s上部署web版macos
前端·macos·kubernetes
qiyi.sky5 分钟前
JavaWeb——Web入门(8/9)- Tomcat:基本使用(下载与安装、目录结构介绍、启动与关闭、可能出现的问题及解决方案、总结)
java·前端·笔记·学习·tomcat
清云随笔26 分钟前
axios 实现 无感刷新方案
前端
鑫宝Code28 分钟前
【React】状态管理之Redux
前端·react.js·前端框架
忠实米线36 分钟前
使用pdf-lib.js实现pdf添加自定义水印功能
前端·javascript·pdf
pink大呲花39 分钟前
关于番外篇-CSS3新增特性
前端·css·css3
少年维持着烦恼.43 分钟前
第八章习题
前端·css·html
我是哈哈hh1 小时前
HTML5和CSS3的进阶_HTML5和CSS3的新增特性
开发语言·前端·css·html·css3·html5·web
田本初1 小时前
如何修改npm包
前端·npm·node.js