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事件将修改后的值传给父组件。数据变了通过动态绑定值影响视图,视图变了通过事件监听影响数据。

相关推荐
訾博ZiBo3 小时前
为什么我的 React 组件会无限循环?—— 一次由 `onClick` 引发的“惨案”分析
前端·react.js
my一阁3 小时前
一文解决Chrome使用
前端·chrome
IT_陈寒3 小时前
SpringBoot性能调优实战:5个让接口响应速度提升300%的关键配置
前端·人工智能·后端
訾博ZiBo4 小时前
告别 v-model 焦虑:在 React 中优雅地处理『双向绑定』
前端·react.js
β添砖java4 小时前
交互动效设计
前端·javascript·交互
简小瑞4 小时前
VSCode用它管理上千个服务:依赖注入从入门到实战
前端·设计模式
骑自行车的码农5 小时前
React 合成事件的设计原理 2
前端·react.js
JamesGosling6665 小时前
详解 Vue 3.6 Vapor Mode:从原理到问题,看透 VDOM 逐步退场的底层逻辑
前端·vue.js
一个很帅的帅哥5 小时前
Vue中的hash模式和history模式
前端·vue.js·history模式·hash模式