93 lines
1.6 KiB
Markdown
93 lines
1.6 KiB
Markdown
---
|
||
title: Vue3 defineModel
|
||
date: 2026-06-05
|
||
---
|
||
|
||
# 一、概念
|
||
  defineModel是对 props + emit的语法糖,返回一个可写的 ref。Vu3.4开始支持。
|
||
  之前的做法:
|
||
```ts
|
||
// 子组件
|
||
const props = defineProps({
|
||
modelValue: Number
|
||
})
|
||
|
||
const emit = defineEmits(['update:modelValue'])
|
||
|
||
function increment() {
|
||
emit('update:modelValue', props.modelValue + 1)
|
||
}
|
||
```
|
||
|
||
  现在做法:
|
||
```ts
|
||
const model = defineModel()
|
||
```
|
||
|
||
# 二、简单示例
|
||
  父组件:
|
||
```vue
|
||
<script setup>
|
||
import Stepper from './Stepper.vue'
|
||
import { ref } from 'vue'
|
||
|
||
const quantity = ref(1)
|
||
</script>
|
||
|
||
<template>
|
||
<div>
|
||
<p>购买数量:{{ quantity }}</p>
|
||
<Stepper v-model="quantity" />
|
||
</div>
|
||
</template>
|
||
```
|
||
|
||
  子组件:
|
||
```vue
|
||
<script setup>
|
||
const model = defineModel({
|
||
type: Number,
|
||
default: 1
|
||
})
|
||
</script>
|
||
|
||
<template>
|
||
<button @click="quantity--">−</button>
|
||
<span>{{ quantity }}</span>
|
||
<button @click="quantity++">+</button>
|
||
</template>
|
||
```
|
||
|
||
  和`defineProps`定义类似,可以指定类型和默认值。
|
||
|
||
# 三、多个v-model
|
||
  父组件:
|
||
```vue
|
||
<UserForm
|
||
v-model:name="form.name"
|
||
v-model:age="form.age"
|
||
/>
|
||
```
|
||
|
||
  子组件:
|
||
```vue
|
||
<script setup lang="ts">
|
||
const name = defineModel<string>('name', {
|
||
default: ''
|
||
})
|
||
|
||
const age = defineModel<number>('age', {
|
||
default: 0
|
||
})
|
||
</script>
|
||
|
||
<template>
|
||
<input v-model="name" placeholder="姓名" />
|
||
<input v-model="age" type="number" placeholder="年龄" />
|
||
</template>
|
||
```
|
||
|
||
::: tip
|
||
defineProps: 只读,不能改
|
||
defineModel: 可写
|
||
::: |