Skip to content

基本用法

父子组件间双向绑定数据

html
父组件:
<child v-model:count="countModel" />
子组件:
const model = defineModel('count')

也可以有更多的控制参数:

ts
const title = defineModel('title', { required: true })

如果 v-model 不带参数,那么 defineModel 默认绑定唯一的那个数据源。 原生组件绑定

html
<script setup>
import Child from './Child.vue'
import { ref } from 'vue'

const msg = ref('Hello World!')
</script>

<template>
  <h1>{{ msg }}</h1>
  <Child v-model:msg="msg" />
</template>

<script setup>
const model = defineModel('msg')
</script>

<template>
  <span>My input</span> <input v-model="model">
</template>

总之,跨组件数据双向绑定相当于使用两次 v-model,并通过 defineModel 将其链接起来。

  • 底层实现参见[[组件通信#v-model 的底层实现]]、

defineModel 返回值

defineModel 返回一个 ref,这个 ref 的 .value 属性与父组件的 v-model 的值保持同步。当这个 ref 在子组件中被修改时,父组件绑定的值也会相应地更新。 返回值中第一个元素是模型的 ref,用于访问和修改模型的值,第二个元素是一个对象,包含了所有添加到 v-model 的修饰符。

自定义自定义组件 v-model 修饰符

获取父组件标签上使用的修饰符

html
<child v-model:count.abcd="countModel" />
ts
const [model, modifiers] = defineModel('count')
console.log(modifiers) // { abcd: true }

自定义修饰符行为 以首字母大写为例:

html
<script setup>
const [model, modifiers] = defineModel({
  set(value) { //重载setter函数,所以可以通过return改变这个ref的.value
    if (modifiers.capitalize) {
      return value.charAt(0).toUpperCase() + value.slice(1)
    }
    return value
  }
})
</script>

<template>
  <input type="text" v-model="model" />
</template>

v-model 绑定的 myText 值发生改变的时候会触发这个 set 函数,解构出修饰符后进行相应的修改操作即可。