v-model 的使用

发布时间 2023-03-25 20:37:55作者: 小阁下

1. v-model 的基本使用

1.1 v-model 是一个语法糖

<template>
  <input :value="text" @input="event => text = event.target.value" />
  <input v-model="text" /> <!-- 这一行的意思和上一行是一样的 -->
</template>
<script setup>
import { ref } from 'vue'
const text = ref('')
</script>

1.2 checkbox 复选框的使用

<template>
  <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>
</template>
<script setup>
import { ref } from 'vue'
const checkedNames = ref([])
</script>

注意这里的 checkedNames 只能是数组, 相应的结果就是选中的 input 所对应的 value 所构成的数组. 如果是其他类型, 则会被转换为 true/false

1.3 radio 单选框的使用

<template>
  <div>Checked names: {{ checkedNames }}</div>

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

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

  <input type="radio" id="mike" value="Mike" v-model="checkedNames">
  <label for="mike">Mike</label>
</template>
<script setup>
import { ref } from 'vue'
const checkedNames = ref('')
</script>

这里的 checkNames 为空字符串, 相应的结果就是选中的 input 所对应的 value, 如果 checkNames 对应的是其他的类型, 其结果也是一样的

1.4 select 选择器的使用

<script setup>
import { ref } from 'vue'

const selected = ref('')
</script>

<template>
  <span> Selected: {{ selected }}</span>

  <select v-model="selected">
    <option disabled value="">Please select one</option>
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
</template>

selected 赋予 <option disabled value="">Please select one</option> 相同的值可以使得 <select> 在初始的时候默认显示这个不会被选中的 <option>

1.5 修饰符

  • .lazy : 一般情况下, v-model 会在 input 事件触发后更新数据, 而在使用 v-model.lazy="value" 后, 其会在 change 事件触发后再更新(change 事件触发的前提是失去焦点)
  • .number : 用户的输入会自动转换为 number 类型
  • .trim : 去除开始和结束两边的空格

2. 对组件使用 v-model

2.1 父子组件间的传值

<!-- 父组件 -->
<template>
  <CustomInput v-model="componentText" />
  <!-- 等价于下面这行代码 -->
  <CustomInput
    :modelValue="componentText"
    @update:modelValue="(newValue) => (componentText = newValue)"
  />

  <CustomInput v-model:mv="componentText" />
  <!-- 可以通过参数指定传递给子组件的变量名 -->
  <CustomInput 
    :mv="componentText" 
    @update:mv="(newValue) => (componentText = newValue)"
  />
</template>

<script lang="ts" setup>
import CustomInput from './CustomInput.vue'
import { ref } from 'vue'
const componentText = ref('')
</script>
<!-- 子组件 -->
<template>
  <input :value="modelValue" @input="handleUpdate" />
</template>

<script lang="ts" setup>
defineProps(['modelValue'])

// 定义 update:modelValue 事件
const emit = defineEmits(['update:modelValue'])

const handleUpdate = (event: Event) => {
  emit('update:modelValue',(event.target as HTMLInputElement).value)
}
</script>

currentTargettarget 的区别

  • currentTarget : 指向的是所绑定事件的元素
  • target : 指向的是触发事件的元素