Vue3双向数据绑定v-model

目录

[1 v-model简介](#1 v-model简介)

[2 v-model原理](#2 v-model原理)

[2.1 核心原理](#2.1 核心原理)

[2.2 修饰符](#2.2 修饰符)

[3 v-model快速上手](#3 v-model快速上手)

[3.1 v-model绑定原生表单](#3.1 v-model绑定原生表单)

[3.2 v-model组件数据传递](#3.2 v-model组件数据传递)

[3.2.1 父子组件通信](#3.2.1 父子组件通信)

[3.2.2 v-model实现父子组件数据传递原理](#3.2.2 v-model实现父子组件数据传递原理)

[3.2.3 更便捷的v-model绑定方法](#3.2.3 更便捷的v-model绑定方法)

[3.2.4 总结](#3.2.4 总结)


1 v-model简介

v-model 是Vue框架的一种内置的API指令,用于处理双向数据绑定,本质是一种语法糖写法。

双向数据绑定是指数据绑定在视图上,视图的改变会影响绑定的数据,而数据的改变又会影响视图的显示。因此常用于表单项,表单元素通过v-model绑定数据,数据变化会影响表单元素的数据显示,而表单内的输入数据又会影响绑定的数据。

html 复制代码
<script setup>
    const message = ref(null)
</script>
<template>
    <input v-model="message" placeholder="输入内容" />
    <p>{{ message }}</p>
</template>

2 v-model原理

2.1 核心原理

上述v-model实际上会被编译器拆解为两个操作:

1.:value的value属性动态绑定。

2.@input输入事件。

即,当input输入框的value发生变化时,事件监听器会执行@input事件绑定的函数,将value的最新值复制到绑定的数据(这里就是message):

html 复制代码
<input 
  :value="message" 
  @input="message = $event.target.value" 
>

2.2 修饰符

.lazy:将input事件转为change事件(失焦后更新)

.number:输入值转为数字类型

.trim:自动去除首尾空格

可以为表单项的v-model添加修饰符,从而形成更多的绑定行为。比如使用.lazy和.trim组合,表单元素发生change事件才会进行数据同步,同时自动去除输入框的首尾空格:

html 复制代码
<input v-model.lazy.trim="text"> 

3 v-model快速上手

3.1 v-model绑定原生表单

除了可以绑定input表单项,还可以绑定如下表单项:

(1)多行文本

html 复制代码
<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<textarea v-model="message" placeholder="add multiple lines"></textarea>

**注意,在textarea使用插值表达式是无效的。**比如下面的行为是错误的:

html 复制代码
<textarea>{{ text }}</textarea>

(2)复选框

单选:

html 复制代码
<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>
javascript 复制代码
const checked = ref(false)

多选:

html 复制代码
    <div>Checked names: {{ checkedNames }}</div>

    <input
      type="checkbox"
      id="jack"
      value="Jack"
      v-model="checkedNames"
    />
    <label for="jack">Jack</label>

    <input
      type="checkbox"
      id="john"
      value="John"
      v-model="checkedNames"
    />
    <label for="john">John</label>

    <input
      type="checkbox"
      id="mike"
      value="Mike"
      v-model="checkedNames"
    />
    <label for="mike">Mike</label>
javascript 复制代码
const checkedNames = ref([])

(3)选项框

html 复制代码
    <div>Selected: {{ selected }}</div>
    <select v-model="selected">
      <option disabled value="">Please select one</option>
      <option>A</option>
      <option>B</option>
      <option>C</option>
    </select>
javascript 复制代码
const selected = ref('')

建议在增加option,属性为disabled和value,即提供一个值为空的禁用选项,该选项会在selected还未有值的时候提供更友好的显示。

3.2 v-model组件数据传递

v-model更常用的用法是父子组件之间的数据传递,在此之前,先来看看常用的两种父子组件的通信方式:父传子(值传递)和子传父(事件传递)。

3.2.1 父子组件通信

(1)父传子

父传子又称为数据下行,父组件通过自定义属性向子组件传递数据,子组件通过props接收:

html 复制代码
<!-- 父组件 -->
<ChildComponent :title="parentTitle" />

<!-- 子组件 -->
<script setup>
defineProps(['title']) // 接收父组件传递的 title
</script>

这种方式是单向数据流,即子组件不可直接修改title数据。

(2)子传父

子传父又称为事件上行,子组件通过$emit触发事件,父组件监听事件并更新数据:

html 复制代码
<!-- 子组件 -->
<button @click="$emit('updateTitle', 'New Title')">修改标题</button>

<!-- 父组件 -->
<ChildComponent @updateTitle="parentTitle = $event" />

3.2.2 v-model实现父子组件数据传递原理

而v-model实现父子组件数据传递的原理正是父子组件通信的两种方式的结合:

html 复制代码
<!-- 父组件 -->
<ChildComponent 
  :modelValue="data" 
  @update:modelValue="data = $event"
/>

<!-- 等价于 -->
<ChildComponent v-model="data" />

即,在父组件中使用子组件,通过v-model绑定data数据,底层会被解析为:modelValue的动态值绑定和@update事件函数。

html 复制代码
<script setup>
defineProps(['modelValue'])
defineEmits(['update:modelValue'])
</script>

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

即,在子组件中,通过props接收父组件的modelValue数据,通过emits来监听modelValue的数据修改事件,一旦子组件的modelValue发生变化,就会通过update事件通知父组件修改数据值。

注意:如果不使用v-model进行父子组件的双向数据绑定,仅想父组件传递数据给子组件,在父组件中使用:value="value"来绑定子组件的数据,子组件使用defineProps来接收该数据。

如果子组件通过事件通知父组件,父组件使用@事件="事件函数"绑定子组件,子组件使用defineEmits接收需要监听的事件即可。

3.2.3 更便捷的v-model绑定方法

在Vue 3.4以后,如下方式子组件可以更便捷的获取到父组件的双向数据绑定:

html 复制代码
<script setup>
const modelValue = defineModel() // 自动关联 Prop 和事件
</script>

<template>
  <input v-model="modelValue" />
</template>

3.2.4 总结

v-model支持父子组件的响应式数据和视图的双向绑定,父组件通过modelValue porps数组将响应式数据传递给子组件,子组件视图变化通过@update:modelValue事件将修改后的值传给父组件。数据变了通过动态绑定值影响视图,视图变了通过事件监听影响数据。

相关推荐
汝生淮南吾在北5 小时前
SpringBoot3+Vue3小区物业报修系统+微信小程序
微信小程序·小程序·vue·毕业设计·springboot·课程设计·毕设
UIUV5 小时前
JavaScript中this指向机制与异步回调解决方案详解
前端·javascript·代码规范
momo1005 小时前
IndexedDB 实战:封装一个通用工具类,搞定所有本地存储需求
前端·javascript
liuniansilence5 小时前
🚀 高并发场景下的救星:BullMQ如何实现智能流量削峰填谷
前端·分布式·消息队列
再花5 小时前
在Angular中实现基于nz-calendar的日历甘特图
前端·angular.js
GISer_Jing5 小时前
今天看了京东零售JDS的保温直播,秋招,好像真的结束了,接下来就是论文+工作了!!!加油干论文,学&分享技术
前端·零售
Mapmost5 小时前
【高斯泼溅】如何将“歪头”的3DGS模型精准“钉”在地图上,杜绝后续误差?
前端
废春啊6 小时前
前端工程化
运维·服务器·前端
爱上妖精的尾巴6 小时前
6-9 WPS JS宏Map、 set、get、delete、clear()映射的添加、修改、删除
前端·wps·js宏·jsa
爱分享的鱼鱼6 小时前
对比理解 Vue 响应式 API:data(), ref、reactive、computed 与 watch 详解
前端·vue.js