Vue3.3新特性-defineModel
Vue2中
v-model
相当于:value和@input
Vue3是进行了统一,让我们的记忆负担更小一些
一、引入
在Vue3中,自定义组件上使用v-model, 相当于传递一个modelValue
属性,同时触发 update:modelValue
事件
我们需要先定义 props,再定义 emits 。其中有许多重复的代码。如果需要修改此值,还需要手动调用 emit 函数。
父组件(180p)
<channel-select v-model="cateId"></channel-select>
子组件
使用工具选中标签
<script setup>
defineProps({
modelValue: {
type: [String, Number]
}
})
const emit = defineEmits(['update:modelValue'])
</script>
<template>
<!-- 一旦这里的value修改了,就会触发事件update:modelValue然后子传父,将得到的值更新到上层的cateId里 -->
<el-select :modelValue="modelValue" @update:modelValue="emit('update:modelValue', $event)">
<el-option></el-option>
</el-select>
</template>
Vue3中相当于将sync语法和:value进行了合并
<channel-select v-model="cateId"></channel-select>
// 等价于,此时:modelValue是可以省略的
<channel-select v-model:modelValue="cateId"></channel-select>
所以它也可以改名字,以下代码等价于 :cid 和 @update:cid 的简写,但使用最多的还是modelValue
<channel-select v-model:cid="cateId"></channel-select>
// 子组件也需要跟着改
defineProps({
cid: {
type: [String, Number]
}
})
const emit = defineEmits(['update:cid'])
// 子组件中使用的地方也需要修改
<el-select :modelValue="cid" @update:modelValue="emit('update:cid', $event)">
二、defineModel
于是乎 defineModel 诞生了。
modelValue接收完后
- 可以直接当做接收过来的props来进行渲染
- 接收过来的数据不再需要emits,可以直接改
三、配置
生效需要配置 vite.config.js
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue({
script: {
// 将defineModel启动起来
defineModel: true
}
}),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})
配置完后记得重启
App.vue
<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>
my-input.vue
<script setup>
import { defineModel } from 'vue'
const modelValue = defineModel()
</script>
<template>
<div>
<input
type="text"
:value="modelValue"
@input="e => modelValue = e.target.value"
>
</div>
</template>