本篇文章主要介绍 v-model 在 Vue2 和 Vue3 中使用变化。

一、Vue2 中 v-model 的使用

v-model 是语法糖,本质还是父子组件间的通信。父子组件通信时有两种方式:

  1. 父给子传值:通过 props
  2. 子给父传值:通过 Events up,使用 $emit 触发事件。

1.1、父组件给子组件传值

父组件代码

<child  :msg="msg"  />
<script>
export default{
data(){
return{
msg:"父组件给子组件传值"
}
}
}
</script>

子组件代码

<template>
<div>
{{msg}}
</div>
</template>
<script>
export default{
props:{
msg:{
type:String,
default:""
}
}
}
</script>

props 是单向数据流,子组件只能读取,并不能修改 msg 。对象类型可以,但不建议修改。

1.2、父子组件双向绑定

子组件同步一个数据的时候,子组件既要使用,还要修改这个数据,以前需要通过 props Down 和 Events Up 来实现。现为了方便,提供了特殊的语法糖 v-model 。

父组件代码:

{{msg}}
<set-input v-model="msg" />

子组件 SetInput.vue 文件代码

<template>
<div>
<input type="text" v-model="newValue">
</div>
</template>
<script>
export default {
props:{
value:{
type:String,
default:''
}
},
computed:{
newValue:{
get:function(){
return this.value
},
set:function(value){
this.$emit('input',value)
}
}
}
}
</script>

v-model = "msg" 可以翻译为:

:value="msg"
@input="msg=$events"

所以父组件的代码可以翻译为:

<set-input :value="msg" @input="msg=$events" />

在一个组件上,v-model 只能使用一次,如果想要对多个数据同步绑定,则可以使用.sync修饰符。

二、.sync修饰符

.sync 和 v-model 都是语法糖,本质还是父子组件间的通信。使用 .sync 修饰符实现父子组件多个数据双向绑定。

因为 vue2 中组件只能定义一个 v-model,如果父子需要实现多个数据双向绑定,就需要借助 .sync 修饰符。

.sync 使用原理:

<child-comp v-model="msg" :foo.sync="foo"  />
//可翻译为
<child-comp
:value="msg" @input="msg=$event"
:foo="foo" @update:foo="foo=$event" />
/*********** 一个完整的代码示例 *************/
//父组件代码
<child-comp v-model="msg" :foo.sync="foo" /> //子组件代码
<template>
<div>
<input type="text" v-model="newFoo">
<input type="text" v-model="newValue">
</div>
</template>
<script>
export default {
props:{
value:{
type:String,
default:''
},
foo:{
type:String,
default:""
}
},
computed:{
newValue:{
get:function(){
return this.value
},
set:function(value){
this.$emit('input',value)
}
},
newFoo:{
get:function(){
return this.foo
},
set:function(value){
this.$emit('update:foo',value)
}
}
}
}
</script>

三、Vue3.x 使用 v-model

vue2 中的 v-model 和 .sync 功能重叠,容易混淆,因此 vue3 做了统一,一个组件可以多次使用 v-model 。

3.1、vue 3 的v-model使用原理:

<child-comp v-model="msg" /> 

//可翻译为
<child-comp :modelValue="msg" @update:modelValue="msg=$event" />

单个数据双向绑定完整示例

//父组件代码
<child-comp v-model="name" /> 子组件代码:
<template>
<input type="text" v-model="newValue">
</template> <script>
export default {
props:{
modelValue:{
type:String,
default:''
}
},
computed:{
newValue:{
get:function(){
return this.modelValue
},
set:function(value){
this.$emit('update:modelValue',value)
}
}
}
}
</script>

vue3 使用特定的 modelValue ,避免 value 的占用,通过 update:modelValue 实现数据双向绑定。值得注意的是,vue3 移除了 model 选项。

3.2、多个 v-model 使用

在 vue3 一个组件可以使用多个 v-model ,统一了 vue2 的 v-model 和 .sync 修饰符。

使用原理:

<child-comp v-model:name="name" v-model:age="age" /> 

  //可翻译为
<child-comp
:name="name" @update:name="name=$event"
:age="age" @update:age="age=$event" />

实现多个数据双向绑定完整实例:

//父组件代码
<child-comp v-model:name="name" v-model:age="age" /> //子组件代码
<template>
<div>
<input type="text" v-model="newName">
<input type="text" v-model="newAge">
</div>
</template>
<script>
export default {
props:{
name:{
type:String,
default:''
},
age:{
type:String,
default:""
}
},
emits:['update:name','update:age'],
computed:{
newName:{
get:function(){
return this.name
},
set:function(value){
this.$emit('update:name',value)
}
},
newAge:{
get:function(){
return this.age
},
set:function(value){
this.$emit('update:age',value)
}
}
}
}
</script>

需要注意的是 script 中多了一个 emits 选项,你发现了吗?

vue3 组件的自定义事件需要定义在 emits 选项中,只要是自定义事件,就需要添加在 emits 中,否则会有警告。它的优点:

  1. 如果与原生事件相同名时,事件就会被触发两次,如果在 emits 选项中加入时,当作自定义事件处理,只会触发一次。
  2. 更好地指示组件的工作方式。
  3. 可以校验对象形式的事件。

四、总结

从 vue2.0 开始,组件上自定义 v-model 进行数据双向绑定,不断改进它的使用。过程如下:

<child-comp v-model="msg" /> 

4.1、vue2.0 可以翻译为:

<child-comp :value="msg" @input="msg=$event" />

存在问题:v-model 和 value 有一个强绑定关系,如果子组件中有一个 input 原生标签,此时就会影响原生标签的 value 和 input 事件。

4.2、vue2.2版本

引入了 model 组件选项,允许开发者任意指定 v-model 的 props 和 event 。这样就解决了 vue2.0 中的 v-model 和 value 的强绑定关系。但是还是存在一个问题,就是多个数据双向绑定时,还是需要借助 .sync 修饰符。

4.3、vue3.x 版本

Vue3 可以翻译为:

<child-comp :modelValue="msg" @update:modelValue="msg=$event" /> 

vue3 统一 使用 v-model 进行多个数据双向绑定,废除了 model 组件选项。


本篇文章的分享到这就要结束了,喜欢小编的欢迎点个关注!

极速上手 VUE 3—v-model 的使用变化的更多相关文章

  1. 极速上手 VUE 3 —— teleport传送门组件

    一.teleport 介绍 teleport 传送门组件,提供一种简洁的方式,可以指定它里面的内容的父元素.通俗易懂地讲,就是 teleport 中的内容允许我们控制在任意的DOM中,使用简单. 使用 ...

  2. 10 分钟上手 Vue 组件 Vue-Draggable

    Vue 综合了 Angualr 和 React 的优点,因其易上手,轻量级,受到了广泛应用.成为了是时下火热的前端框架,吸引着越来越多的前端开发者! 本文将通过一个最简单的拖拽例子带领大家快速上手 V ...

  3. 详解Vue 如何监听Array的变化

    详解Vue 如何监听Array的变化:https://www.jb51.net/article/162584.htm

  4. 手牵手,从零学习Vue源码 系列二(变化侦测篇)

    系列文章: 手牵手,从零学习Vue源码 系列一(前言-目录篇) 手牵手,从零学习Vue源码 系列二(变化侦测篇) 陆续更新中... 预计八月中旬更新完毕. 1 概述 Vue最大的特点之一就是数据驱动视 ...

  5. 应用wavesurfer.js绘制音频波形图小白极速上手总结

    一.简介 1.1  引   人生中第一份工作公司有语音识别业务,需要做一个web网页来整合语音引擎的标注结果和错误率等参数,并提供人工比对的语音标注功能(功能类似于TranscriberAG等),(博 ...

  6. 快速上手Vue

    课程目录: ES6常用语法 Vue基础以及指令 Vue组件 Vue-Router Vue生命周期 npm webpack vue-cli Vuex以及axios

  7. Vue中的model

    v-model语法糖: model: 默认情况下,一个组件上的 v-model 会把 value 用作 prop 且把 input 用作 event, 但是一些输入类型比如单选框和复选框按钮可能想使用 ...

  8. firewalld 极速上手指南

    从CentOS6迁移到7系列,变化有点多,其中防火墙就从iptables变成了默认Firewalld服务.firewalld网上资料很多,但没有说得太明白的.一番摸索后,总结了这篇文章,用于快速上手. ...

  9. 第 2 篇:上手 Vue 展示 todo 列表

    作者:HelloGitHub-追梦人物 追梦人物的 Vue 系列教程在他的博客已经全部更新完成,地址: https://www.zmrenwu.com/courses/vue2x-todo-tutor ...

随机推荐

  1. 记一次docker compose的低级错误

    记一次docker compose的低级错误 问题 ​ 今天在学习dockercompose的时候,启动docker compose up,结果却出现异常 Error response from da ...

  2. STM32,下载HAL库写的代码后J-Link识别不到芯片,必须要按住复位才能下载?

    问题描述:最近在学STM32的HAL库,据说可以统一STM32江湖,前途无量.最近一段时间参照STM32CubeMX和原子的资料自己学着建了两个HAL库的工程模板,F4的还好说,F1的出现了一个玄学问 ...

  3. 让PHP能够调用C的函数-FFI扩展

    在大型公司中,一般会有很我编程语言的配合.比如说让 Java 来做微服务层,用 C++ 来进行底层运算,用 PHP 来做中间层,最后使用 JS 展现效果.这些语言间的配合大部分都是通过 RPC 来完成 ...

  4. 【TP3.2.3】根据字段统计条数

    // 省份查询 $province = M('hospital') -> field('area as label,count(*) as value') -> group('area') ...

  5. 数据库的高可用MHA实验步骤

    一.多机互信的步骤 双机互信的步骤 第一步:在master管理服务器上ssh-keygen 在master同一台管理服务器上重新开一个窗口ssh-copy-id 192.168.0.13自己给自己互信 ...

  6. Go语言核心36讲(Go语言基础知识二)--学习笔记

    02 | 命令源码文件 我们已经知道,环境变量 GOPATH 指向的是一个或多个工作区,每个工作区中都会有以代码包为基本组织形式的源码文件. 这里的源码文件又分为三种,即:命令源码文件.库源码文件和测 ...

  7. 超详细的Eureka源码解析

    Eureka简介 Eureka是什么? Eureka是基于REST(Representational State Transfer)服务,主要以AWS云服务为支撑,提供服务发现并实现负载均衡和故障转移 ...

  8. [AGC023D] Go Home 题解

    题目传送门 Solution 首先排除掉特殊情况:若 \(S\) 在两侧,肯定会顺序/逆序直接走完,答案就是边界减去出发点. 考虑到若 \(P_1\geq P_n\),那么显然 \(1\) 不到家 \ ...

  9. Netty-FastThreadLocal快在哪里呢?

    来源于:https://www.wangdaye.net/archives/n-e-t-t-y-zhi-f-a-s-t-t-h-r-e-a-d-l-o-c-a-l 前言 netty的concurren ...

  10. 项目优化之v-if

    前言: 在vue项目中,由于功能比较多,需要各种条件控制某个功能.某个标签.表格中的某一行是否显示等,需要使用大量的v-if来判断条件. 例如: <div v-if="isShow(a ...