Vue3中的常见组件通信之v-model

news2024/11/20 11:50:23

Vue3中的常见组件通信之v-model

概述

​ 在vue3中常见的组件通信有props、mitt、v-model、 r e f s 、 refs、 refsparent、provide、inject、pinia、slot等。不同的组件关系用不同的传递方式。常见的撘配形式如下表所示。

组件关系传递方式
父传子1. props
2. v-model
3. $refs
4. 默认插槽、具名插槽
子传父1. props
2. 自定义事件
3. v-model
4. $parent
5. 作用域插槽
祖传孙、孙传祖1. $attrs
2. provide、inject
兄弟间、任意组件间1. mitt
2. pinia

​ props和自定义事件详见本人另一篇文章:
Vue3中的常见组件通信之props和自定义事件
mitt用法详见本人另一篇文章:
Vue3中的常见组件通信之mitt
下面接着前面的文章继续记录v-model的用法。

4.v-model

v-model常用于普通html标签中的双向绑定,这个绑定用法无法实现跨组件通信,v-model用在组件标签中的时候,可以实现父子间的组件通信,而这样通信方式常用于UI组件库。要理解UI组件库的v-model的双向通信原理,需要先明白普通html标签中的v-model的底层原理。

4.1 普通HTML标签中v-model实现双向绑定的底层原理

在普通html标签中用v-model可以实现数据的双向绑定,如下代码所示是把input输入框里的数据与username进行双向绑定:

<template>
  <div class="father">
    <h3>父组件</h3>    
    <br>
    <input id="input1" type="text" v-model="username">
  </div>
</template>

<script setup lang="ts" name="Father">
	import { ref } from "vue"; 
  // 数据
  let username = ref('zhansan')

</script>

<style scoped>
.father {
  height: 300px;
  padding: 20px;
  color: #ffffff;  
  text-align:center; 
  background-image: url(https://xyyhxxx.oss-cn-beijing.aliyuncs.com/picGoImg/202406041301030.png);
  background-size: cover
}
#input1{
  color: #000;
}
</style>

运行后在浏览器打开vue开发者工具,如下图所示:

上图中更改vue开发者工具中的username的值页面也会跟着发生变化,这个实现的是把数据呈现在页面,如果修改input输入框中的内容,username的数据也会跟着发生改变,这个实现的是页面传向数据,这就双向绑定中的双向,而实现这个双向绑定的关键就是在于input标签中写了v-model,如下所示:

<input id="input1" type="text" v-model="username">

而上面的代码实现的底层原理是这样的,先把上面的代码改成如下图所示:

<input id="input1" type="text" :value="username">

这样可以实现数据呈现在页面,数据修改页面也会跟着修改,但是修改页面,数据却不会变化,这只实现了一个方向的数据绑定,接着再给input标签增加属性,如下代码:

<input 
       id="input1" 
       type="text" 
       :value="username" 
       @input="username=$event.target.value"
       >

这样再测试,就会发现页面中的数据也可以传向数据了,修改input标签中的内容,数据也会变化。

注意上面代码中@input="username= e v e n t . t a r g e t . v a l u e " 这句代码 t s 会报警,我们需要处理一下,对 event.target.value"这句代码ts会报警,我们需要处理一下,对 event.target.value"这句代码ts会报警,我们需要处理一下,对event.target进行断言,报警就会消失:

<input 
      id="input1" 
      type="text" 
      :value="username" 
      @input="username=(<HTMLInputElement>$event.target).value"
      >

普通input标签中v-model实现双向绑定的底层原理就是:value+@input事件。

4.2组件标签中v-model中实现双向绑定

首先准备一个自己的UI组件,作为子组件,代码如下:

<template>
    <input type="text">
</template>

<script setup lang="ts" name="MyInput">

</script>

<style scoped>
    input{
        background-color:transparent;
        color: #ffffff;
        border: 0px;
        border-bottom: 1px solid #ffffff ;
        margin: 5px;
    }
</style>

然后在父组件中引入:

//引入MyInput组件
  import MyInput from "./MyInput.vue";

在父组件中把MyInput组件呈现在页面中:

<label>用户名:<MyInput/></label>

运行效果如下:

image-20240604213607959

这样效果出来了,但是没有还没有实现数据绑定,首先在MyInput组件标签上增加:modelValue属性和绑定@update:model-value事件,如下代码:

<MyInput :modelValue="username" @update:model-value="username=$event"/>

然后需要在MyInput组件中声明props和声明事件来接收数据和事件:

//接收props
defineProps(["modelValue"])
//声明事件
let emit = defineEmits(['update:model-value'])

最后在MyInput组件中的普通html标签中添加:value属性和绑定@input事件:

<input 
       type="text" 
       :value="modelValue"
       @input="emit('update:model-value',(<HTMLInputElement>$event.target).value)"
>

至此,已经实现了父组件和子组件MyInput组件的双向通信,如下图所示:

最后在父组件中的MyInput组件标签上可以直接简写为如下代码:

<MyInput v-model="username"/>

实现的效果是完全一样的。

我们在用UI组件库的时候可以直接这样写,前提是UI组件库已经处理好了底层逻辑。

以下是完整代码:

父组件:

<template>
  <div class="father">
    <h3>父组件</h3>    
    <br>
    <!-- <input id="input1" type="text" v-model="username"> -->

    <!-- 下面是v-model 的本质 -->
    <!-- <input 
      id="input1" 
      type="text" 
      :value="username" 
      @input="username=(<HTMLInputElement>$event.target).value"
      > -->
    
    <!-- 下面是v-model 的本质 -->
    <!-- <label>用户名:<MyInput :modelValue="username" @update:model-value="username=$event"/></label> -->

    <label>用户名:<MyInput v-model="username"/></label>

  </div>
</template>

<script setup lang="ts" name="Father">
	import { ref } from "vue"; 
  //引入MyInput组件
  import MyInput from "./MyInput.vue";
  // 数据
  let username = ref('zhansan')

</script>

<style scoped>
.father {
  height: 300px;
  padding: 20px;
  color: #ffffff;  
  text-align:center; 
  background-image: url(https://xyyhxxx.oss-cn-beijing.aliyuncs.com/picGoImg/202406041301030.png);
  background-size: cover
}
#input1{
  color: #000;
}
</style>

MyInput组件:

<template>
    <input 
        type="text" 
        :value="modelValue"
        @input="emit('update:model-value',(<HTMLInputElement>$event.target).value)"
    >
</template>

<script setup lang="ts" name="MyInput">
    //声明props
    defineProps(["modelValue"])
    //声明事件
    let emit = defineEmits(['update:model-value'])
</script>

<style scoped>
    input{
        background-color:transparent;
        color: #ffffff;
        border: 0px;
        border-bottom: 1px solid #ffffff ;
        margin: 5px;
    }
</style>

4.3一个UI组件实现多个数据传送

在父组件中可以改value,比如改成usName,如下代码所示:

<MyInput v-model:usName="username"/>

这个代码的本质是如下代码:

<MyInput :usName="username" @update:usName="username=$event"/>

在MyInput组件代码中就需要改成如下代码:

<template>
    <input 
        type="text" 
        :value="usName"
        @input="emit('update:usName',(<HTMLInputElement>$event.target).value)"
    >
</template>

<script setup lang="ts" name="MyInput">
    //声明props
    defineProps(["usName"])
    //声明事件
    let emit = defineEmits(['update:usName'])
</script>

这样改完后运行效果跟之前是完全一样的,接下来再扩展一下,父组件中的MyInput标签改成如下代码:

<MyInput v-model:usName="username" v-model:paword="password"/>

然后在MyInput组件中代码改成如下:

<template>
    <input 
        type="text" 
        :value="usName"
        @input="emit('update:usName',(<HTMLInputElement>$event.target).value)"
    >
    <br>
    <input 
        type="text" 
        :value="paword"
        @input="emit('update:paword',(<HTMLInputElement>$event.target).value)"
    >
</template>

<script setup lang="ts" name="MyInput">
    //声明props
    defineProps(["usName",'paword'])
    //声明事件
    let emit = defineEmits(['update:usName','update:paword'])
</script>

这样就实现一个组件内双向绑定两个数据了,如下图所示:

4.4小结

v-model可以实现父子间的通信,v-model即可以设置在普通html标签中,也可以设置在组件标签中,设置在组件标签中可以实现父子间的双向通信,前提是子组件底层做了处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1791478.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

插件:Plugins

一、安装网格插件

配置 HTTP 代理 (HTTP proxy)

配置 HTTP 代理 [HTTP proxy] 1. Proxies2. curl2.1. Environment2.2. Proxy protocol prefixes 3. Use an HTTP proxy (使用 HTTP 代理)3.1. Using the examples (使用示例)3.1.1. Linux or macOS3.1.2. Windows Command Prompt 3.2. Authenticating to a proxy (向代理进行身…

springboot大学生就业管理系统-计算机毕业设计源码89344

摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对大学生就业管理系统等问题&#xff0c;对大…

apache poi 插入“下一页分节符”并设置下一节纸张横向的一种方法

一、需求描述 我们知道&#xff0c;有时在word中需要同时存在不同的节&#xff0c;部分页面需要竖向、部分页面需要横向。本文就是用java调用apache poi来实现用代码生成上述效果。下图是本文实现的效果&#xff0c;供各位看官查阅&#xff0c;本文以一篇课文为例&#xff0c;…

el-table动态配置显示表头

在实际工作中&#xff0c;会遇到动态配置e-table表头的情况&#xff0c;如下方法可以实现&#xff1a; // 要展示的列 column: [{prop: name, name: 名称 }, {prop: age, name: 年龄 }, {prop: sex, name: 性别 }, {prop: address, name: 地址 }, {prop: city, name: 城市 }]…

【HarmonyOS】List组件多层对象嵌套ForEach渲染更新的处理

【HarmonyOS】List组件多层对象嵌套ForEach渲染更新的处理 问题背景&#xff1a; 在鸿蒙中UI更新渲染的机制&#xff0c;与传统的Android IOS应用开发相比。开发会简单许多&#xff0c;开发效率提升显著。 一般传统应用开发的流程处理分为三步&#xff1a;1.画UI&#xff0c;…

webservice、WCF、webAPI、MVC权限认证

webservice 权限认证 》》soapHeader SOAPHeader案例 服务引用下生成的服务方法参数中会自动加入一个soapHeader的参数&#xff0c; WEB服务引用则没有&#xff0c;我感觉采用WEB服务引用基于这种验证比较方便&#xff0c; 因为只需将soapHeader实例赋值一次就可以多次调用不…

不是,有了这套IP地址管理开源系统谁还用Excel啊

号主&#xff1a;老杨丨11年资深网络工程师&#xff0c;更多网工提升干货&#xff0c;请关注公众号&#xff1a;网络工程师俱乐部 中午好&#xff0c;我的网工朋友。 作为网工的我们想必都很清楚IP地址管理的重要性以及其复杂性&#xff0c;传统的Excel表格虽然在某些情况下能…

Nodejs-- 网络编程

网络编程 构建tcp服务 TCP tcp全名为传输控制协议。再osi模型中属于传输层协议。 tcp是面向连接的协议&#xff0c;在传输之前需要形成三次握手形成会话 只有会话形成了&#xff0c;服务端和客户端才能想发送数据&#xff0c;在创建会话的过程中&#xff0c;服务端和客户…

强化训练:day12(删除公共字符、两个链表的第一个公共结点、mari和shiny)

文章目录 前言1. 删除公共字符1.1 题目描述1.2 解题思路1.3 代码实现 2. 两个链表的第一个公共结点2.1 题目描述2.2 解题思路2.3 代码实现 3. mari和shiny3.1 题目描述3.2 解题思路3.3 代码实现 总结 前言 1. 删除公共字符   2. 两个链表的第一个公共结点   3. mari和shiny…

jenkins应用2-freestyle-job

1.jenkins应用 1.jenkins构建的流程 1.使用git参数化构建&#xff0c;用标签区分版本 2.git 拉取gitlab远程仓库代码 3.maven打包项目 4.sonarqube经行代码质量检测 5.自定义制作镜像发送到远程仓库harbor 6.在远程服务器上拉取代码启动容器 这个是构建的整个过程和步骤…

基于Django的博客系统之用HayStack连接elasticsearch增加搜索功能(五)

上一篇&#xff1a;搭建基于Django的博客系统数据库迁移从Sqlite3到MySQL&#xff08;四&#xff09; 下一篇&#xff1a;基于Django的博客系统之增加类别导航栏&#xff08;六&#xff09; 功能概述 添加搜索框用于搜索博客。 需求详细描述 1. 添加搜索框用于搜索博客 描…

Windows安装ElasticSearch版本7.17.0

在Windows系统上本地安装Elasticsearch的详细步骤如下&#xff1a; 1. 下载Elasticsearch 访问 Elasticsearch下载页面。选择适用于Windows的版本7.17.0&#xff0c;并下载ZIP文件。 2. 解压文件 下载完成后&#xff0c;找到ZIP文件&#xff08;例如 elasticsearch-7.17.0.…

Windows端口本地转发

参考 微软Netsh interface portproxy 命令 界面端口代理的 Netsh 命令 | Microsoft Learn 使用Windows系统的portproxy功能配置端口转发 使用Windows系统的portproxy功能配置端口转发-阿里云帮助中心 (aliyun.com) 将来自0.0.0.0地址对端口35623的访问转发到172.18.106.16…

Locality-aware subgraphs for inductive link prediction in knowledge graphs

Locality-aware subgraphs for inductive link prediction in knowledge graphs a b s t r a c t 最近的知识图&#xff08;KG&#xff09;归纳推理方法将链接预测问题转化为图分类任务。 他们首先根据目标实体的 k 跳邻域提取每个目标链接周围的子图&#xff0c;使用图神经网…

Docker最新超详细版教程通俗易懂

文章目录 一、Docker 概述1. Docker 为什么出现2. Docker 的历史3. Docker 能做什么 二、Docker 安装1. Docker 的基本组成2. 安装 Docker3. 阿里云镜像加速4. 回顾 hello-world 流程5. 底层原理 三、Docker 的常用命令1. 帮助命令2. 镜像命令dokcer imagesdocker searchdocker…

【云岚家政】-day00-开发环境配置

文章目录 1 开发工具版本2 IDEA环境配置2.1 编码配置2.2 自动导包设置2.3 提示忽略大小写2.4 设置 Java 编译级别 3 Maven环境3.1 安装Maven3.2 配置仓库3.3 IDEA中配置maven 4 配置虚拟机4.1 导入虚拟机4.2 问题 5 配置数据库环境5.1 启动mysql容器5.2 使用MySQL客户端连接数据…

GPT革命:AI如何重塑我们的未来!

GPT革命&#xff1a;AI如何重塑我们的未来&#xff01; &#x1f604;生命不息&#xff0c;写作不止 &#x1f525; 继续踏上学习之路&#xff0c;学之分享笔记 &#x1f44a; 总有一天我也能像各位大佬一样 &#x1f3c6; 博客首页 怒放吧德德 To记录领地 &#x1f31d;分享…

视创云展元宇宙虚拟展厅,带来沉浸式的逛展体验!

近年来&#xff0c;随着科技的飞速发展和市场需求的不断演变&#xff0c;众多企业纷纷将目光转向线上虚拟展厅的建设。视创云展元宇宙虚拟展厅凭借其创新性和实用性&#xff0c;为众多企业带来了前所未有的宣传体验&#xff0c;成为了商企展示自我、推广产品的全新舞台。 与传统…

K210视觉识别模块学习笔记4: 训练与使用自己的模型_识别字母

今日开始学习K210视觉识别模块: 模型训练与使用_识别字母 亚博智能的K210视觉识别模块...... 固件库: maixpy_v0.6.2_52_gb1a1c5c5d_minimum_with_ide_support.bin 文章提供测试代码讲解、完整代码贴出、测试效果图、测试工程下载 这里也算是正式开始进入到视觉识别的领域了…