目录

1 v-model简介

2 v-model原理

2.1 核心原理

2.2 修饰符

3 v-model快速上手

3.1 v-model绑定原生表单

3.2 v-model组件数据传递

3.2.1 父子组件通信

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

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

3.2.4 总结


1 v-model简介

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

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

<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):

<input 
  :value="message" 
  @input="message = $event.target.value" 
>

2.2 修饰符

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

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

        .trim:自动去除首尾空格

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

<input v-model.lazy.trim="text"> 

3 v-model快速上手

3.1 v-model绑定原生表单

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

        (1)多行文本

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

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

<textarea>{{ text }}</textarea>

        (2)复选框

        单选:

<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>
const checked = ref(false)

        多选:

    <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>
const checkedNames = ref([])

        (3)选项框

    <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>
const selected = ref('')

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

3.2 v-model组件数据传递

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

3.2.1 父子组件通信

        (1)父传子

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

<!-- 父组件 -->
<ChildComponent :title="parentTitle" />

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

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

        (2)子传父

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

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

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

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

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

<!-- 父组件 -->
<ChildComponent 
  :modelValue="data" 
  @update:modelValue="data = $event"
/>

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

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

<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以后,如下方式子组件可以更便捷的获取到父组件的双向数据绑定:

<script setup>
const modelValue = defineModel() // 自动关联 Prop 和事件
</script>

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

3.2.4 总结

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

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐