前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >在 Vue 中创建自定义输入

在 Vue 中创建自定义输入

作者头像
疯狂的技术宅
发布于 2019-03-28 02:58:06
发布于 2019-03-28 02:58:06
6.6K00
代码可运行
举报
文章被收录于专栏:京程一灯京程一灯
运行总次数:0
代码可运行

基于组件的库或框架(如 Vue )可以创建 可重用组件 ,它能在各自应用程序中相互传递数据,这些框架能确保这些数据是一致的,并且(希望)简化了它们的使用方式。

特别地,表单输入往往会有很多复杂性,我们希望把这些复杂性都隐藏在组件中,例如 自定义设计 、标签、验证、帮助消息等等,并且我们还要确保这些部分中的每一个都按正确的顺序排列渲染。

除此之外,Vue还有一个内置的 v-model 指令,通过绑定一个值并捕获输入事件来 模拟双向绑定 。如果要构建自定义输入组件,我们一定会想到直接使用 v-model 指令。

可悲的是,当我在 Vue 中查看单选按钮或复选框的自定义输入的示例时,他们根本没有考虑 v-model ,或者没有正确的使用。对于自定义文本输入有一些不错的文档,但由于它们没有解释自定义的单选框或复选框,我们将在本文进行讨论。

本教程旨在...

  1. 了解 v-model 如何在原生输入上工作,主要侧重于单选框和复选框
  2. 默认情况下,了解 v-model 在自定义组件上的工作原理
  3. 了解如何创建自定义复选框和单选,以模拟原生 v-model 的工作原理

开始之前的小提示 :整个代码示例中使用 ES2015+ 代码,我也会赞成使用 Vue.componentnew Vue 的单一文件组件 语法。

v-model 是如何正常工作的?

官方Vue文档 在这个话题上写得其实很不错,但是还有一些小盲点。无论如何,我们将会深入研究。

实质上, v-model 只是一个缩写的指令,它给我们提供了双向的数据绑定,代码是否缩写就取决于它使用的输入类型。

文本框

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<input v-model="message" placeholder ="edit me"> <p>message: {{message}} </p>  <!-- or -->  <p>message: </p> <p style="white-space:pre-line"> {{message}} </p> <textarea v-model="message" placeholder="add multiple lines"></textarea> 

当使用文本 input(包括emailnumber等)或 textarea 时, v-model="varName"等价于 :value="varName" @input="e => varName = e.target.value" 。 这意味着每次输入完成后的 varName 将被更新为输入的值,然后输入的值被设置为 varName 。 正常的 select 元素也会像这样,尽管 multiple 多项选择有所不同。

单选按钮

那么,单选按钮呢?

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<input type="radio" value="One" v-model="pick"> <input type="radio" value="Two" v-model="pick"> <span>选择:{{pick}} </span> 

这相当于:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<input type="radio" value="One" :checked="picked == 'One'" @change="e => pick = e.target.value"> <input type="radio" value="Two" :checked="picked == 'Two'" @change="e => pick = e.target.value"> <span>picked: {{pick}}</span> 

注意 v-model 甚至没有触及 value 。它仍然在 change事件的处理程序中做同样的事情(尽管现在是 change 而不是 input),但是现在根据 picked是否与该单选按钮的值相同来确定 checked 是 true 还是 false。

复选框

复选框有点难以谈论,因为它们有两种不同的行为,这取决于是否只有一个具有给定v-model或多个的复选框。

如果您使用单个复选框,则 v-model 会将其视为布尔值,并忽略该 value

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<input type="checkbox" value="foo" v-model="isChecked"> 

与以下代码相同

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<input type="checkbox" value="foo" :checked="!!isChecked" @change="e => isChecked = e.target.checked"> 

如果想要它是非布尔值 ,可以使用 true-valuefalse-value 属性,它控制当选择复选框时,模型将被设置成什么值。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<input type="checkbox" value="foo" v-model="isChecked" true-value="1" false-value="0"> 

与以下代码相同

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<input type="checkbox" value="foo" :checked="isChecked =='1'" @change="e => isChecked = e.target.checked?'1':'0'"> 

单一复选框的情况差不多就是这样。如果有多个复选框共享一个模型,那么这些复选框将填充一个数组,其值为所有勾选了的复选框,但一定要确保传入的模型是数组类型,否则会产生一些奇怪的行为。并且 true-valuefalse-value 属性不再有效。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>   <div>     <input type="checkbox" value="foo" v-model="checkedVals">     <input type="checkbox" value="bar" v-model="checkedVals">     <input type="checkbox" value="baz" v-model="checkedVals">   </div> </template> <script>    export default {      data:() =>{      checkedVals: ['bar']      }}  </script>  

在模版中很难保证一致性,所以我将一些逻辑转移到组件的方法上:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>   <div>     <input type ="checkbox" value ="foo" v-model ="checkedVals">     <input type ="checkbox" value ="bar" v-model ="checkedVals">     <input type ="checkbox" value ="baz" v-model ="checkedVals">   </div> </template> <script>  export default {    data: () {      return {checkedVals:['bar']}    },    method: {      shouldBeChecked(val) {        return this.checkedVals.includes(val)      }updateVals(e) {        let isChecked = e.target.checked        let val = e.target.value       if(isChecked) {          this.checkedVals.push(val)        } else {          this.checkVals.splice(this.checkedVals.indexOf(val)1}      }    }  }  </script> 

这比我们以前看过的要复杂得多,但如果你把它分解下来,也不算太糟糕。当该复选框的值包含在数组中时, shouldBeCheckedtrue ,否则为 falseupdateVals将复选框中选中的值添加到数组,并且在取消选中时删除它。

v-model 如何在组件上工作?

由于 Vue 不知道我们的组件应该如何工作,或者 Vue 试图作为某种输入类型的替代,v-model 会一致对待所有的组件。它实际上的工作方式与文本输入情况下完全相同,只是在事件处理程序中,它不会将事件对象传递给它,而是希望将值直接传递给它。 所以

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<my-custom-component v-model="myProperty"/> 

与以下代码相同

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<my-custom-component :value="myProperty" @input="val => myProperty = val" /> 

组件中可以使用 model 属性改写为如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export default {   name: 'my-custom-component',   model: {     prop:'foo',     event:'bar'   }// ... } 

v-model 将查看这些属性,而不会使用 value 属性。它将使用在 prop 指定的属性,而不是侦听 input 事件,它将使用在 event中指定的 event。 所以上面的 my-custom-component 示例实际上等价于以下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<my-custom-component :foo ="myProperty" @bar="val => myProperty = val"/> 

这很赞,但如果我们制作一个自定义单选或复选框,这还不够好。尽管通过这些工作,我们可以将 v-model 使用的逻辑转移到我们的定制组件中的单选和复选框。

支持 v-model 的自定义单选框

与复选框相比,定制单选框相当简单。以下是一个非常基本的自定义单选框,仅仅将 input 包装在标签中,并接受 label 属性来添加 label 文本。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>   <label>     <input type="radio" :checked="shouldBeChecked" :value="value" @change="updateInput">     {{ label }}   </label> </template> <script>    export default {      model: {        prop: 'modelValue',        event: 'change'      },      props:  {        value: {          type:  string,         },         modelValue: {           default: ""          },         label:  {           type:  string,           required: true         }},       computed: {         shouldBeChecked() {           return this.modelValue == this.value         }       }       method: {         updateInput() {           this.$emit('change'this.value)         }       }     }   </script>

注意 :为了有助于解释这些应用程序如何与 v-model 配合使用,我上面只用了 props,但 input 标签还可以利用其他几个属性(例如 namedisabled ),因此请确保创建好了所需要的 props 并将其传递给 input。还可以通过添加WAI-ARIA属性 ,以及使用slots 添加内容,而不是像上面在 label 里的 props。

由于本示例中没有包含 name,可以认为一组单选框之间将不会实际上彼此同步。实际上,model 的更新将依次更新共享该 model 的其他单选按钮,因此只要共享相同的 model,他们就不需要像普通 HTML 表单一样分享一个共同的名字。

支持 v-model 的自定义复选框

使自定义复选框比单选按钮明显更复杂,主要是因为我们必须支持两种不同的用例:单个 true/false 复选框(可能使用或不使用 true-value 和/或 false-value )和多个复选框将所有检查的值合并到一个数组中。

那么我们如何确定哪个用例呢?你可能会认为我们需要确定是否有其他复选框具有相同的 name 属性,但这并不是 Vue 的内置系统所使用的。就像单选框一样,Vue 根本不考虑 name 属性,它只是在本地提交表单时使用。那么你可能认为它会根据是否有其他复选框共享相同的 model 来确定,但也不是这样。它是由模型是否是数组来决定的,仅此而已。

因此,代码将按照自定义单选按钮的代码进行结构化,但是在内部的 shouldBeCheckedupdateInput 将根据是否是一个数组而进一步细化。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>   <label>     <input type="checkbox" :checked="shouldBeChecked" :value="value" @change="updateInput">     {{ label }}   </label> </template> <script>    export default {      model: {        prop: 'modelValue',        event: 'change'      },      props:  {        value: {          type:  String,         },         modelValue: {           default: false         },         label:  {           type:  String,           required: true         }// 我们将 `true-value` 和 `false-value` 设置为 true 和 false         // 我们可以随时使用它们,而不用检查它们是否被设置。         // 也可以在这里使用驼峰命名,但要用连字符分隔属性名称         // 使用组件时仍然有效         trueValue: {           default: true         },         falseValue: {           default: false         }       },       computed: {         shouldBeChecked() {           if(this.modelValue instanceof Array){             return this.modelValue.includes(this.value)           }           // 请注意,"true-value" 和 "false-value" 是 JS 中的驼峰命名          return this.modelValue === this.trueValue         }       },       method: {         updateInput(event) {           let isChecked = event.target.checked           if(this.modelValue instanceof Array){             let newValue = [... this.modelValue]             if(isChecked){               newValue.push(THIS.VALUE)             } else {               newValue.splice(newValue.indexOf(this.value),1)             }             this.$emit('change',newValue)           } else {             this.$emit('change',isChecked ? this.trueValue : this.falseValue)           }         }       }     }   </script>   

这就完成啦。但是将其分解成两个不同的组件可能会更好:一个用于处理单个 true/false 切换,一个用于选项列表。这将允许它更紧密地遵循单一责任原则,但如果你正在寻找选择框的替代品,那么这就是你正在寻找的(加上所有其他有用的属性和自定义功能的添加)。

本文转载自:众成翻译

译者:smartsrh 链接:http://www.zcfy.cc/article/3866

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-08-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 京程一灯 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
英伟达A800也要禁售了?国产GPU厂商们准备好了吗
在没有获得许可证的情况下,美国商务部将禁止英伟达等制造商向中国客户运送AI芯片。英伟达专供中国的A800芯片,在无许可证的情况下也将被禁售。
数据猿
2023/09/27
1.1K0
英伟达A800也要禁售了?国产GPU厂商们准备好了吗
芯片界地震!国产GPU狂飙,英伟达霸权终结者?
目前,国内已经进入大模型的规模化商用阶段,而大模型非常“吃”GPU。但是,由于美国限制,英伟达的GPU供应不上了。
数据猿
2023/11/14
5320
芯片界地震!国产GPU狂飙,英伟达霸权终结者?
英伟达H20芯片:适应市场变化的战略调整
在全球科技领域中,人工智能(AI)技术的发展正以前所未有的速度推动着产业变革。作为全球领先的GPU制造商之一,英伟达公司始终站在技术创新的前沿。然而,在国际政治经济形势的影响下,英伟达面临着前所未有的挑战。为了应对这些挑战并保持市场领先地位,英伟达推出了专为中国市场设计的H20芯片。本文将深入探讨H20芯片的技术特点、市场定位、竞争格局及其对未来AI产业发展的影响。 一、背景与挑战 在过去的几年里,国际形势的变化对高科技产业产生了深远影响。特别是针对尖端技术的出口管制政策,使得像英伟达这样的国际巨头不得不重新审视其全球战略。面对这一现实,英伟达采取了一系列措施,包括推出H20芯片以适应新的市场环境。
用户7353950
2024/11/23
6320
英伟达H20芯片:适应市场变化的战略调整
从英伟达 vs ATI的芯片大战看GPU前世今生
1998年英伟达宣布GPU的研发成功,是计算机显示的历史性突破。此后,20世纪70年代末到1998年被称为pre-GPU时代,即前GPU时代,1998年以后则被称为GPU时代。
IT阅读排行榜
2020/02/20
2.4K0
从英伟达 vs ATI的芯片大战看GPU前世今生
财报小高峰后,英伟达难逃疫情市场和竞争长考
相信很多人都见过英伟达标志性的LOGO——一只绿色的眼睛加上它的英文名“NVIDIA”。
刘旷
2020/02/25
5710
英伟达发布ChatGPT专用GPU,推理速度提升了10倍
机器之心报道 编辑:泽南、蛋酱 AI 的 iPhone 时刻,要有一块好的芯片。 曾何几时,人工智能因为算力不足进入了长达数十年的瓶颈,GPU 点燃了深度学习。在 ChatGPT 时代,AI 因为大模型再次面临算力不足的问题,这一次英伟达还有办法吗? 3 月 22 日,GTC 大会正式召开,在刚刚进行的 Keynote 上,英伟达 CEO 黄仁勋搬出了为 ChatGPT 准备的芯片。 「加速计算并非易事,2012 年,计算机视觉模型 AlexNet 动用了 GeForce GTX 580,每秒可处理 26
机器之心
2023/03/29
1.1K0
英伟达发布ChatGPT专用GPU,推理速度提升了10倍
英伟达首席架构师:GPU性能濒临极限,但我们还有很多压榨套路
说到 GPU 的未来,没有人能比英伟达首席科学家,美国国家工程院、文理科学学院院士,计算机架构大师 Bill Dally 更有资格发表观点了。
机器之心
2021/06/08
5200
不堪忍受英伟达霸权,微软、OpenAI纷纷自研AI芯片
英伟达是当之无愧的“AI算力王者”,A100、H100系列芯片占据金字塔顶尖位置,是ChatGPT这样的大型语言模型背后的动力来源。
科技云报道
2023/10/16
3190
不堪忍受英伟达霸权,微软、OpenAI纷纷自研AI芯片
台积电联手英伟达押注「硅光赛道」,真技术还是炒概念?
一个属于硅光芯片的“黄金时代”。 作者 | 来自镁客星球的家衡 随着台积电2nm计划逐渐明朗,这场关于先进制程的多方混战似乎提前宣告结束,但这家半导体巨头的野心似乎远不止于此——在先进封装领域,台积电也是动作频频。 近日,据台媒《电子时代》报道,台积电深度参与了一项由英伟达牵头的研发项目,该项目将使用台积电COUPE(紧凑型通用光子引擎)封装技术,将多个AI GPU组合成一块GPU。 单看项目本身,这似乎与年初爆火的Chiplet概念大同小异,但整篇报道却指向了另一项技术——硅光子(SiPH)。 此外文章还
镁客网
2022/09/19
6930
台积电联手英伟达押注「硅光赛道」,真技术还是炒概念?
搅局者联发科用“AI定义座舱”,能打破高通座舱垄断吗?
前言:在生成式端侧大模型上车、算力进化等技术背景下,智能座舱产业的市场机遇和竞争格局正在发生巨变。联发科正凭借“AI定义座舱”,加速赶超竞品,以实现智能座舱产业的重塑。
芯智讯
2024/04/30
1880
搅局者联发科用“AI定义座舱”,能打破高通座舱垄断吗?
英伟达、AMD 高端芯片断供,国产芯片如何迅速崛起
大数据文摘转载自AI科技大本营 整理:苏宓 出品:CSDN 8 月 31 日,据外媒 Protocol、路透社等多家报道,美国开始对出口人工智能相关应用所需的先进芯片施加新的限制,其中 AMD、NVIDIA(英伟达)等半导体巨头受到了直接的影响。 英伟达的 A100、H100、A100X 均被限制 英伟达在周三披露的一份文件中证实了这一消息的真实性,其表示,"2022 年 8 月 26 日,美国政府(或称 USG)通知 NVIDIA,USG 对公司 A100 和即将推出的 H100 集成电路今后向中国(包
大数据文摘
2022/09/06
4620
英伟达、AMD 高端芯片断供,国产芯片如何迅速崛起
华为达芬奇与英伟达CUDA,必有一战!
——聚焦数据 · 改变商业 当初英特尔和微软,搞出来个Wintel,制霸电脑时代很多年。
数据猿
2024/05/30
4840
华为达芬奇与英伟达CUDA,必有一战!
AI 芯片的未来之战:“霸主”英伟达真就无人能挡了吗?
作者 | NICOLE KOBIE 译者 | 王强 策划 | 刘燕 英伟达的 GPU 统治了 AI 芯片市场。但众多初创企业表示,快速发展的人工智能领域需要新的架构。 1英伟达,AI 芯片市场的统治者 业内有一个传说,讲的是英伟达怎样从游戏和图形硬件转向了 AI 芯片市场的统治者 — 这个故事中有猫的身影。 早在 2010 年,现任英伟达首席科学家 Bill Dally 有一天正与斯坦福大学的前同事、计算机科学家吴恩达共进早餐,当时吴正在与谷歌合作一个项目。“他试图在互联网上找猫 — 他描述的不是那样,但
深度学习与Python
2023/04/01
8750
AI 芯片的未来之战:“霸主”英伟达真就无人能挡了吗?
英伟达显卡:AI时代的无冕之王
在当今的人工智能(AI)时代,显卡已经从仅仅是游戏和图形处理的工具,转变为了深度学习和AI应用的重要驱动力。在这个领域,英伟达显卡无疑是一位无冕之王。那么,究竟是什么让英伟达显卡在AI领域独领风骚呢?让我们通过对比其主要竞争对手AMD和Intel,深入探讨英伟达显卡的优势。
码事漫谈
2025/01/08
2640
英伟达显卡:AI时代的无冕之王
高光后再转身,英伟达的AI芯片进阶之路
最近,端测的AI推理芯片市场一片火热,英伟达和英特尔正面对垒,初创企业如履寒冰。而云上AI训练市场,已经从早期的GPU一统天下,发展到如今多方势力割据的局面。
镁客网
2019/12/18
8150
“绝杀”中国AI,美国会打英伟达这张牌吗?
4 月 24 日,美国总统特朗普宣布,美国财政部长姆努钦以及贸易代表莱特希泽将在几天内率团访问中国,进行贸易谈判。此外,特朗普还积极评价了习近平主席最近关于中国进一步开放的讲话。
AI科技大本营
2018/07/23
4850
“绝杀”中国AI,美国会打英伟达这张牌吗?
高调发布史上最大GPU后,英伟达却宣布暂停自动驾驶路测
英伟达股价瞬间下跌3.8%。 北京时间3月28日凌晨,英伟达创始人&CEO黄仁勋在CTC 2018(英伟达CPU技术大会)上发表演讲,并发布了迄今最大的GPU——DGX-2。但令人震惊的是,黄仁勋紧接着宣布,暂定自动驾驶路测。 随后英伟达股价应声下跌3.8%。 高调发布史上最大GPU后 英伟达却宣布暂停自动驾驶研发 大会一开场,黄仁勋便推出光线追踪RTX技术(ray-tracing),该技术可提供电影级画质的实时渲染,渲染出逼真的反射、折射和阴影画面。 随后,英伟达发布了新一代显卡NVIDIA Quadro
镁客网
2018/05/29
5100
英伟达和AI算力芯片的军备竞赛
虽然英伟达的股价从本周早些时候的峰值回落,但其股价在过去一年中飙升了262%,从每股近242美元飙升至收盘时的875美元。
AsicWonder
2024/03/11
1580
英伟达和AI算力芯片的军备竞赛
中、美巨头自研芯片“围剿”英伟达
“芯事重重”是腾讯科技半导体产业研究策划,本期聚焦科技公司下场自研AI芯片的逻辑与挑战。
小腾资讯君
2024/08/02
1750
英伟达 GTC 大会携万亿参数 GPU「炸裂」 AI 行业
北京时间3月19日凌晨4点,英伟达公司创始人兼CEO黄仁勋踏上了美国加州圣何塞SAP中心的舞台,开始讲述 2024 GTC 主题演讲《见证AI的变革时刻》。
AI科技评论
2024/03/25
1390
英伟达 GTC 大会携万亿参数 GPU「炸裂」 AI 行业
推荐阅读
相关推荐
英伟达A800也要禁售了?国产GPU厂商们准备好了吗
更多 >
LV.1
这个人很懒,什么都没有留下~
目录
  • v-model 是如何正常工作的?
    • 文本框
    • 单选按钮
    • 复选框
  • v-model 如何在组件上工作?
    • 支持 v-model 的自定义单选框
  • 支持 v-model 的自定义复选框
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档