当前位置: 首页 > news >正文

Vue 自定义组件实现 v-model 的几种方式

前言

在 Vue 中,v-model 是一个常用的指令,用于实现表单元素和组件之间的双向绑定。当我们使用原生的表单元素时,直接使用 v-model 是很方便的,但是对于自定义组件来说,要实现类似的双向绑定功能就需要一些额外的处理。

本篇文章将介绍几种在自定义组件中实现 v-model 的方式,主要如下:

  • 使用 v-model 属性:适用于表单元素

  • 定义 model 属性:适用于非表单元素

除了以上的两种方式外,还有我们通常使用的`.sync`  修饰符[1](2.3.0+ 新增),主要区别在于使用方式的不同,前者直接使用 v-model,后者使用 .sync 修饰符进行绑定

一. 单向数据流

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。

注意:每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。虽然可以,但是如果你这样做了,Vue 会在浏览器的控制台中发出警告。

二. 基础原理浅析

v-model 实际上就是 props:value$emit('input') 的组合语法糖,简单来说,v-model 的使用其实做了两个比较重要的操作,理解这两个操作,我们就可以轻松实现组件的自定义 v-model

  1. v-bind 绑定 value 属性的值 - props:value;

  2. v-on 绑定 input 事件监听到函数中,函数会获取最新的值赋值到绑定的属性中 - $emit('input');

三. 实现 v-model 的两种方式

1. 直接使用 v-model 属性

适用于表单元素,或者原组件已经实现了 v-model,需要我们进行二次封装

以 input 表单元素为例,在 vue 中,我们可以直接使用 v-model 进行绑定数据,当我们在实现自定义组件custom-component进行封装 input 时,我们的组件对外暴露时也需要使用 v-model,看下面我们应该如何实现:

在自定义组件中,我们可以通过在组件内部使用 value 属性和手动触发 input 事件来实现 v-model 的双向绑定效果。具体实现如下:

<template><input v-model="newValue" />
</template><script>export default {props: {value: {type: Boolean,default: false,},},computed: {newValue: {get() {return this.value;},set(val) {this.$emit("input", val);},},},};
</script>

使用custom-component

<custom-component v-model="newValue" />

在上述代码中,我们通过 value 属性接收父组件传入的值,并且使用 computed 的 set 属性用来监听值的更新,手动触发 $emit('input', value) 来将新值传递给父组件,从而实现双向绑定的效果。

2. 定义 model 属性

适用于非表单元素,完全非表单元素自定义的组件

Vue 允许我们在定义组件中通过定义 model 属性来简化 v-model 的使用。通过定义 model 属性,我们可以指定组件中哪个属性的值应该作 v-model 的值。

假如我们实现一个计数器的组件custom-counter,在页面中显示两个按钮,点击按钮可以进行数值的加减操作,具体示例如下:

<template><div><button @click="increment">+</button><span>{{ value }}</span><button @click="decrement">-</button></div>
</template><script>export default {// 当 model 为默认值时,可以将其省略model: {prop: "value", // 默认是 valueevent: "input", // 默认是 input},props: {value: {type: Number,default: 0,},},methods: {increment() {this.$emit("input", this.value + 1);},decrement() {this.$emit("input", this.value - 1);},},};
</script>

提示:当 model 为默认值时,可以将其省略

父组件中使用custom-counter

<template><div><custom-counter v-model="count"></custom-counter><p>计数器的值为:{{ count }}</p></div>
</template><script>import CustomCounter from "./CustomCounter.vue";export default {components: {CustomCounter,},data() {return {count: 0,};},};
</script>

演示效果如下图所示:

record.gif

在上面的示例中,CustomCounter组件接收一个value属性来接收父组件传递的值,并在点击按钮时修改value属性的值。通过调用this.$emit('input', newValue)触发input事件,将新的value值传递给父组件进行更新。

在父组件中,使用v-model将父组件中的count属性绑定到CustomCounter组件的value属性上,绑定 input 事件监听到函数中,从而实现了数据的双向绑定。

model 是允许 vue 自定义组件使用 v-model 的关键,虽然有时我们不显性的使用它,也不影响我们在自定义组件中使用 v-model 指令,这只是因为被设置默认值。而有的时候,显示的使用,并自定义 model 的 prop 和 event 会有益。

注意:允许一个自定义组件在使用 v-model 时定制 prop 和 event。默认情况下,一个组件上的 v-model 会把 value 用作 prop 且把 input 用作 event,但是一些输入类型比如单选框和复选框按钮可能想使用 value prop 来达到不同的目的。使用 model 选项可以回避这些情况产生的冲突。

四. .sync 修饰符

适用于提供于多个双向绑定的 prop,灵活提供你想要绑定的 property 名

在有些情况下,我们可能需要对一个 prop 进行 “双向绑定”。但是,真正的双向绑定会带来维护上的问题,因为子组件可以变更父组件,且在父组件和子组件两侧都没有明显的变更来源。

这也是为什么我们推荐以 update:myPropName 的模式触发事件取而代之。

举个例子,还是上面的计数器的例子,在一个包含 count prop 的计数组件中,我们可以用以下方法表达对其赋新值的意图:

this.$emit("update:count", newCount);

然后父组件可以监听那个事件并根据需要更新一个本地的数据 property。例如:

<custom-counter v-bind:count="count" v-on:update:count="count = $event" />

我们为这种模式提供一个缩写,即 .sync 修饰符,如下:

<custom-counter :count.sync="count"></custom-counter>

以上的两种写法是等价的

注意:带有 .sync 修饰符的 v-bind 不能和表达式一起使用 (例如 v-bind:count.sync=”count + 1” 是无效的)。取而代之的是,你只能提供你想要绑定的 property 名,类似 v-model。

五. 总结

本篇文章介绍了在 Vue 自定义组中实现 v-model 的几种方式,包括定义 model 属性和使用 v-model 属性。通过以上案例实际分析,相信大家都已经了解这几种方式的创建以及应用场景,以便更加灵活地应用到实际项目中。

以上面两种方式为例,我们可以灵活地根据自己的需求选择合适的方式来实现自定义组件 v-model。如果是表单元素,可以直接使用 v-model 属性;如果是非表单元素,可以通过定义 model 属性指定组件中哪个属性的值应该作 v-model 的值。

除此之外,使用 .sync 修饰符也是进行自定义组件双向绑定的优秀选择,因此在实际开发中,选择适合自己项目需求的方式是最重要的。

参考资料

Prop

自定义事件

.sync 修饰符

相关文章:

Vue 自定义组件实现 v-model 的几种方式

前言 在 Vue 中&#xff0c;v-model 是一个常用的指令&#xff0c;用于实现表单元素和组件之间的双向绑定。当我们使用原生的表单元素时&#xff0c;直接使用 v-model 是很方便的&#xff0c;但是对于自定义组件来说&#xff0c;要实现类似的双向绑定功能就需要一些额外的处理…...

Python Pandas数据处理效率提升指南

大家好&#xff0c;在数据分析中Pandas是Python中最常用的库之一&#xff0c;然而当处理大规模数据集时&#xff0c;Pandas的性能可能会受到限制&#xff0c;导致数据处理变得缓慢。为了提升Pandas的处理速度&#xff0c;可以采用多种优化策略&#xff0c;如数据类型优化、向量…...

最大正方形 Python题解

最大正方形 题目描述 在一个 n m n\times m nm 的只包含 0 0 0 和 1 1 1 的矩阵里找出一个不包含 0 0 0 的最大正方形&#xff0c;输出边长。 输入格式 输入文件第一行为两个整数 n , m ( 1 ≤ n , m ≤ 100 ) n,m(1\leq n,m\leq 100) n,m(1≤n,m≤100)&#xff0c;接…...

ubuntu中软件的进程管理-结束软件运行

在Ubuntu系统中&#xff0c;当某个运行中的软件无法正常退出时&#xff0c;可以通过以下几种方法强制结束该软件&#xff1a; 方法一&#xff1a;使用系统监视器&#xff08;System Monitor&#xff09;–小白专属 这个相当于win上的资源管理器 打开系统监视器 可以通过点击屏…...

Windows环境部署Oracle 11g

Windows环境部署Oracle 11g 1.安装包下载2. 解压安装包3. 数据库安装3.1 执行安装脚本3.2 电子邮件设置3.3 配置安装选项3.4 配置系统类3.5 选择数据库安装类型3.6 选择安装类型3.7 数据库配置3.8 确认安装信息3.9 设置口令 Oracle常用命令 2023年10月中旬就弄出大致的文章&…...

C语言进阶【8】--联合体和枚举(联合体和枚举这么好用,你不想了解一下吗?)

本章概述 联合体类型的声明联合体的特点联合体的大小的计算枚举类型的声明枚举类型的优点枚举类型的使用枚举类型的大小彩蛋时刻&#xff01;&#xff01;&#xff01; 联合体类型的声明 概述&#xff1a;联合体的关键字为 union。它的结构和结构体是一样的。进行展示&#xf…...

Android OTA升级

针对Android系统OTA升级&#xff0c;MTK平台有相关介绍文档&#xff1a;https://online.mediatek.com/apps/faq/detail?faqidFAQ27117&listSW 概念一&#xff1a;OTA包的构建 AOSP full build&#xff1a;Android原生提供的全量包的构建&#xff0c;意思就是可以从任何一…...

【项目经验分享】深度学习自然语言处理技术毕业设计项目案例定制

以下毕业设计是与深度学习自然语言处理&#xff08;NLP&#xff09;相关的毕业设计项目案例&#xff0c;涵盖文本分类、生成式模型、语义理解、机器翻译、对话系统、情感分析等多个领域&#xff1a; 实现案例截图&#xff1a; 基于深度学习的文本分类系统基于BERT的情感分析系…...

一觉醒来,YOLO11 冷不丁就来了

&#x1f947; 版权: 本文由【墨理学AI】原创首发、各位读者大大、敬请查阅、感谢三连 &#x1f389; 声明: 作为全网 AI 领域 干货最多的博主之一&#xff0c;❤️ 不负光阴不负卿 ❤️ 文章目录 前言&#xff1a;一觉醒来&#xff0c;YOLO11 冷不丁就来了ultralytics 版本更新…...

智能编辑器、版本控制与自动化脚本

在繁忙的工作中&#xff0c;每个开发者都渴望拥有一个“秘密武器”&#xff0c;帮助自己提升效率、减少错误&#xff0c;从而更快地完成任务。那么&#xff0c;在众多编程工具中&#xff0c;哪一款能够成为你的工作效率翻倍的“秘密武器”呢&#xff1f;本文将探讨智能的代码编…...

jenkinsfile实现镜像构建、发布

实现代码打包编译 容器镜像构建 jenkins编译采用docker构建。 遇到问题: 1.需要限制docker 容器的内存和cpu docker { image ‘ccr.ccs.tencentyun.com/libary/maven:3.6.3-jdk-8’ args “-v ${WORKSPACE}:/workspace --memory‘2048m’ --cpus‘1’” } 2.jenkins构建需要限制…...

OSPF路由计算

关于OSPF路由的基础概述可以看看这篇博客 动态路由---OSPF协议基础https://blog.csdn.net/ZZZCY2003/article/details/141335261 区域内路由计算 LSA概述 LSA是OSPF进行路由计算的关键依据OSPF的LSU报文可以携带多种不同类型的LSA各种类型的LSA拥有相同的报文头部 重要字段解…...

【设计模式-迭代】

定义 迭代器模式&#xff08;Iterator Pattern&#xff09;是一种行为型设计模式&#xff0c;用于提供一种顺序访问集合对象元素的方式&#xff0c;而不暴露该对象的内部表示。通过迭代器&#xff0c;客户端可以在不需要了解集合实现的细节的情况下遍历集合中的元素。 UML图 …...

k8s搭建双主的mysql8集群---无坑

《k8s搭建一主三从的mysql8集群---无坑-CSDN博客》通过搭建一主三从&#xff0c;我们能理解到主节点只有1个&#xff0c;那么承担增删改主要还是主节点&#xff0c;如果你在从节点上去操作增删改操作&#xff0c;数据不会同步到其他节点。本章我们将实现多主&#xff08;双主&a…...

Iterm2配置主题和Oh-My-Zsh

文章目录 一、配置主题1.1 安装使用git1.2 安装手册1.2.1 激活使用主题 二、配置oh-my-zsh2.1、oh-my-zsh插件2.2、oh-my-zsh主题 [Zsh](http://zsh.org/)2.2.1、Install using Git2.2.2、Install manually2.2.3、Activating theme2.2.4、Install using [zplug](https://github…...

html+css+js实现step进度条效果

实现效果 代码实现 HTML部分 <div class"box"><ul class"step"><li class"circle actives ">1</li><li class"circle">2</li><li class"circle">3</li><li class&quo…...

OpenCV视频I/O(8)视频采集类VideoCapture之从视频源中读取一帧图像函数read()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 抓取、解码并返回下一个视频帧。 cv::VideoCapture::read() 是 VideoCapture 类的一个成员函数&#xff0c;用于从视频源中读取一帧图像. 该方法…...

深度学习500问——Chapter17:模型压缩及移动端部署(2)

文章目录 17.4.6 低秩分解 17.4.7 总体压缩效果评价指标有哪些 17.4.8 几种轻量化网络结构对比 17.4.9 网络压缩未来研究方向有哪些 17.5 目前有哪些深度学习模型优化加速方法 17.5.1 模型优化加速方法 17.5.2 TensorRT加速原理 17.5.3 TensorRT如何优化重构模型 17.5.4 Tensor…...

【C#】DllImport的使用

DllImport 是 C# 中用于从非托管 DLL&#xff08;动态链接库&#xff09;中导入函数的一个特性。这个特性允许你在 .NET 应用程序中调用由其他语言编写的函数&#xff0c;如 C 或 C。使用 DllImport 可以让你重用现有的非托管代码&#xff0c;而不需要重新实现这些功能。 下面…...

基于 Redis 实现滑动窗口的限流

⏳ 限流场景&#xff1a;突发流量&#xff0c;恶意流量&#xff0c;业务本身需要 基于 Redis 实现滑动窗口的限流是一种常见且高效的做法。Redis 是一种内存数据库&#xff0c;具有高性能和支持原子操作的特点&#xff0c;非常适合用来实现限流功能。下面是一个使用 Redis 实现…...

Camera Raw:打开图像

在图像工作流程中&#xff0c;无论是 Raw 格式图像文件还是 JPEG、TIFF 文件&#xff0c;都可以先使用 Camera Raw 打开并调整后&#xff0c;再进入其它 Adobe 软件如 Photoshop 中进行进一步的编辑和处理。 一、打开 Raw 格式图像 1、通过 Adobe Bridge 打开 在 Adobe Bridge …...

RK3588主板PCB设计学习(六)

可以在其它层对过孔进行削盘处理&#xff0c; 可以看到&#xff0c;这里有些过孔用不上&#xff0c;在这一层进行了削盘处理&#xff1a; 对于这种电源层进行铺铜操作的时候&#xff0c;如果不进行削盘处理的话这些焊盘可能导致这个电源层面不完整&#xff0c;存在割裂的风险&a…...

论文阅读(十一):CBAM: Convolutional Block Attention Module

文章目录 IntroductionConvolutional Block Attention ModuleExperimentsConclusion 论文题目&#xff1a;CBAM: Convolutional Block Attention Module&#xff08;CBAM&#xff1a;卷积注意力机制&#xff09;   论文链接&#xff1a;点击跳转   代码链接&#xff1a;Git…...

【Kubernetes】常见面试题汇总(四十八)

目录 108.考虑一家拥有非常分散的系统的跨国公司&#xff0c;希望解决整体代码库问题。您认为公司如何解决他们的问题&#xff1f; 109.我们所有人都知道从单服务到微服务的转变从开发方面解决了问题&#xff0c;但在部署方面却增加了问题。公司如何解决部署方面的问题&#x…...

Qt Creator安卓环境配置【筑基篇】

1.前言 由于我的Qt Creator目前就先的14版本IDE老是存在各种莫名奇妙的bug&#xff0c;我都已经成为官方Qt Forum官方论坛的常客了。有一说一新版本的各种设置不小心误触是真的坑死人。不说了给我小主机配置安卓环境了。小主机系统版本window11-23H,Qt-Creator版本是13.01版本…...

利用SpringBoot构建高效社区医院平台

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…...

【C++ 前缀和 数论】1590. 使数组和能被 P 整除|2038

本文涉及的基础知识点 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 质数、最大公约数、菲蜀定理 LeetCode 1590. 使数组和能被 P 整除 给你一个正整数数组 nums&#xff0c;请你移除 最短 子数组&#xff08;可以为 空&#xff09;&am…...

外部引入的 JavaScript 放置位置

部引入的 JavaScript 通常有两种常见的放置位置&#xff0c;每个位置都有其优缺点&#xff0c;具体取决于页面的需求和性能优化目标&#xff1a; 1. 放在页面的 <head> 标签中 这种方式在 HTML 文档的 <head> 部分引入 JavaScript 文件。 <head><scrip…...

【tbNick专享】虚拟机域控、成员服务器、降级等管理

在 VMware 中完成四台域控服务器、一台成员服务器的创建、降级域控为成员服务器&#xff0c;并创建子域的操作。 1. 创建四台域控和一台成员服务器 1.1 在 VMware 中创建虚拟机 启动 VMware Workstation&#xff1a; 打开 VMware Workstation&#xff0c;点击 “创建新的虚拟…...

Raspberry Pi3B+之Rpanion(gst)和ffmpeg验证

Raspberry Pi3B之Rpanion-gst和ffmpeg验证 1. 源由2. 分析3. 环境搭建步骤1&#xff1a;安装镜像步骤2&#xff1a;系统更新步骤3&#xff1a;安装numpy组件步骤4&#xff1a;安装python3-picamera2组件步骤4&#xff1a;安装cv2组件步骤5&#xff1a;安装ffmpeg组件步骤6&…...

找人做网站 自己购买服务器/线上拓客渠道有哪些

漏洞背景2020年12月08日&#xff0c;OpenSSL官方发布安全公告&#xff0c;披露CVE-2020-1971 OpenSSL GENERAL_NAME_cmp拒绝服务漏洞。OpenSSL是一个开放源代码的软件库包&#xff0c;应用程序可以使用这个包来进行安全通信&#xff0c;避免窃听&#xff0c;同时确认另一端连接…...

wordpress英文模版/北京优化网站推广

bintray上传使用的插件很多&#xff0c;我看到的有android-maven-plugin&#xff0c;gradle-bintray-plugin等等&#xff0c;但是都没有novoda/bintray-release来的简单&#xff0c;下面介绍一下这个插件的使用&#xff0c;其开源库在这里&#xff1a;https://github.com/novod…...

前端做的网站/站长工具seo综合查询问题

中国石油大学华东2013-2014-2C语言A卷&#xff21;卷2013—2014学年第2学期《计算机程序设计 C(2-2)》期末考试试卷专业班级姓名学号开课系室计算机应用技术系考试日期2014年6月22日题号一二三总分得分阅卷人一、程序阅读题(每空2分&#xff0c;共20分)1&#xff0e;又是一年一…...

怎么做网站滑动图片部分h5/免费做网站网站的软件

https://zhidao.baidu.com/question/1494951482361210539.html转载于:https://www.cnblogs.com/SEC-fsq/p/7602426.html...

教育培训推广网站模板/福州百度关键词优化

...

做网站 怎么赚钱吗/百度指数电脑版

2019独角兽企业重金招聘Python工程师标准>>> 原因&#xff1a;开发的jdk 为1.8 64位 生产的是1.7 32位 结论&#xff1a;开发与生产环境要保持一致 转载于:https://my.oschina.net/springMVCAndspring/blog/1600882...