全面剖析Vue3 全新特性 defineModel
一、defineModel 是什么?
defineModel 是 Vue 3.4 引入的一個(gè)編譯器宏,用于簡(jiǎn)化組件雙向數(shù)據(jù)綁定的實(shí)現(xiàn)。它是對(duì) v-model 指令在組件上使用的語(yǔ)法糖,讓開(kāi)發(fā)者可以更簡(jiǎn)潔地實(shí)現(xiàn)父子組件之間的雙向數(shù)據(jù)同步。
二、核心優(yōu)勢(shì)
- 代碼簡(jiǎn)化:減少樣板代碼,不再需要手動(dòng)定義
props和emit - 類型安全:完美支持 TypeScript 類型推斷
- 功能強(qiáng)大:內(nèi)置支持修飾符處理
- 開(kāi)發(fā)體驗(yàn):更直觀的雙向綁定實(shí)現(xiàn)方式
三、基礎(chǔ)用法
3.1 基本實(shí)現(xiàn)
子組件實(shí)現(xiàn):
<template>
<div>
<input
type="text"
:vaule="modelValue"
@input="e => modelValue = e.target.value"
>
</div>
</template>
<script setup>
import { defineModel } from 'vue';
const modelValue = defineModel()
</script>父組件使用:
<script setup >
import myinput from '@/components/my-input.vue';
import { ref } from 'vue'
const txt = ref('123456')
</script>
<template>
<div>
<myinput v-model="txt"></myinput>
{{ txt }}
</div>
</template>3.2 等效的傳統(tǒng)實(shí)現(xiàn)
在沒(méi)有 defineModel 時(shí),我們需要這樣寫:
<script setup>
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
</script>
<template>
<input
type="text"
:value="props.modelValue"
@input="emit('update:modelValue', $event.target.value)"
>
</template>四、高級(jí)特性
4.1 多 v-model 支持
子組件:
<script setup>
const firstName = defineModel('firstName')
const lastName = defineModel('lastName')
</script>
<template>
<input v-model="firstName">
<input v-model="lastName">
</template>父組件:
<UserForm v-model:first-name="firstName" v-model:last-name="lastName" />
4.2 類型定義
<script setup lang="ts">
// 帶類型的 defineModel
const count = defineModel<number>('count', { default: 0 })
// 復(fù)雜類型
interface User {
name: string
age: number
}
const user = defineModel<User>('user')
</script>4.3 修飾符處理
父組件使用修飾符:
<MyInput v-model.trim="text" />
子組件處理修飾符:
<script setup>
const [modelValue, modifiers] = defineModel({
// setter 中可以訪問(wèn) modifiers
set(value) {
if (modifiers.trim) {
return value.trim()
}
return value
}
})
</script>五、實(shí)現(xiàn)原理
defineModel 在編譯階段會(huì)被轉(zhuǎn)換為:
- 一個(gè)
modelValueprop - 一個(gè)
update:modelValue事件 - 一個(gè)計(jì)算屬性,提供 getter 和 setter
編譯后的代碼類似于:
const props = defineProps({
modelValue: { type: String }
})
const emit = defineEmits(['update:modelValue'])
const modelValue = computed({
get() {
return props.modelValue
},
set(value) {
emit('update:modelValue', value)
}
})六、最佳實(shí)踐
命名規(guī)范:
單一模型使用 defineModel()
多個(gè)模型使用 defineModel('name')
默認(rèn)值設(shè)置:
const value = defineModel({
default: ''
})復(fù)雜驗(yàn)證:
const age = defineModel({
type: Number,
validator: (v) => v >= 0
})與原生輸入組件結(jié)合:
<input :value="modelValue" @input="modelValue = $event.target.value" >
七、對(duì)比傳統(tǒng)方式
| 特性 | defineModel | 傳統(tǒng)方式 |
|---|---|---|
| 代碼量 | 1行聲明 | 需要props + emit |
| 類型支持 | 自動(dòng)推斷 | 需要手動(dòng)定義 |
| 多模型支持 | 參數(shù)指定名稱 | 需多個(gè)props/emit |
| 修飾符處理 | 內(nèi)置支持 | 需要手動(dòng)實(shí)現(xiàn) |
| 兼容性 | Vue 3.4+ | 所有Vue3版本 |
八、實(shí)際案例
自定義計(jì)數(shù)器組件
Counter.vue:
<script setup>
const count = defineModel<number>({ default: 0 })
</script>
<template>
<button @click="count--">-</button>
<span>{{ count }}</span>
<button @click="count++">+</button>
</template>父組件使用:
<template>
<Counter v-model="quantity" />
<p>當(dāng)前數(shù)量:{{ quantity }}</p>
</template>
<script setup>
const quantity = ref(1)
</script>九、注意事項(xiàng)
- 版本要求:必須使用 Vue 3.4 或更高版本
- 單向數(shù)據(jù)流:雖然看起來(lái)像雙向綁定,但仍然是單向數(shù)據(jù)流
- 復(fù)雜邏輯:對(duì)于復(fù)雜場(chǎng)景,仍然可以使用傳統(tǒng)方式
- Ref解包:在模板中會(huì)自動(dòng)解包,無(wú)需
.value
defineModel 是 Vue 3.4 中非常實(shí)用的新特性,它大幅簡(jiǎn)化了組件雙向綁定的實(shí)現(xiàn)代碼,同時(shí)保持了類型安全和靈活性。對(duì)于新項(xiàng)目,強(qiáng)烈推薦使用這種方式來(lái)實(shí)現(xiàn) v-model 功能。
到此這篇關(guān)于全面剖析Vue3 全新特性 defineModel 的文章就介紹到這了,更多相關(guān)vue defineModel 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
前端設(shè)置cookie之vue-cookies使用及說(shuō)明
這篇文章主要介紹了前端設(shè)置cookie之vue-cookies使用及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05
vue3如何實(shí)現(xiàn)PDF文件在線預(yù)覽功能
PDF文件在線預(yù)覽的功能相信大家都是有遇到過(guò)的,下面這篇文章主要給大家介紹了關(guān)于vue3如何實(shí)現(xiàn)PDF文件在線預(yù)覽功能的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06
Vue.js中關(guān)于偵聽(tīng)器(watch)的高級(jí)用法示例
Vue.js 提供了一個(gè)方法 watch,它用于觀察Vue實(shí)例上的數(shù)據(jù)變動(dòng)。下面這篇文章主要給大家介紹了關(guān)于Vue.js中關(guān)于偵聽(tīng)器(watch)的高級(jí)用法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2018-05-05
解決vue prop傳值default屬性如何使用,為何不生效的問(wèn)題
這篇文章主要介紹了解決vue prop傳值default屬性如何使用,為何不生效的問(wèn)題。具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09
基于Vue uniapp實(shí)現(xiàn)貪吃蛇游戲
貪吃蛇游戲想必是很多70、80后的回憶,一直到現(xiàn)在也深受大家的喜歡。本文將利用Vue+uniapp實(shí)現(xiàn)這一經(jīng)典的游戲,感興趣的可以了解一下2022-04-04
Vue用v-for給循環(huán)標(biāo)簽自身屬性添加屬性值的方法
這篇文章主要介紹了Vue用v-for給循環(huán)標(biāo)簽自身屬性添加屬性值的方法,文中大家給大家列舉了三種方法 ,需要的朋友可以參考下2018-10-10
前端vue打包項(xiàng)目,如何解決跨域問(wèn)題
這篇文章主要介紹了前端vue打包項(xiàng)目,如何解決跨域問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05

