当我们在 Vue 3 中处理表单输入时,经常会使用 v-model
来实现数据的双向绑定。然而,在某些情况下,我们可能需要对 v-model
进行一些额外的处理,例如对输入值进行格式化、验证或者其他操作。这时,可以使用 const model = defineModel();
来简化 v-model
的使用,并使代码更加清晰和易于维护。
问题背景
在 Vue 3 中,当我们想要创建一个带有自定义逻辑的双向绑定输入框时,通常会这样写:
javascript
<template>
<el-select style="width:100%;" :size="styleSize" clearable filterable @change="changeData" v-model="selectValue"
placeholder="请选择">
<el-option
v-for="item in options"
:key="item.dataCode"
:label="item.dataCode"
:value="item.dataValue">
</el-option>
</el-select>
</template>
<script>
export default {
name: "nb-select",
props: ['value', "catalog", "size"],
data: function () {
return {
selectValue: "",
loading: false,
options: [],
styleSize: "normal"
}
},
mounted: function () {
console.info("init");
this.loadData();
this.selectValue = this.value;
if (this.size != null && this.size != "") {
this.styleSize = this.size;
}
},
watch: {
value: function (val) {
this.selectValue = val;
}
},
methods: {
async loadData() {
let param = {};
param.dictKey = this.catalog;
let res = await this.$http.form("/dictItem/list", param);
if (res.code === 200) {
this.options = res.data;
}
},
changeData(value) {
console.info(value);
this.$emit('input', value);
}
}
}
</script>
<style scoped>
</style>
这种方式虽然可以实现双向绑定,但是当涉及到多个输入框时,代码会显得重复而冗长。
使用 const model = defineModel();
Vue 3 提供了一个工具函数 defineModel()
,它可以帮助我们简化 v-model
的使用,并更好地组织代码。
javascript
<template>
<el-select style="width:100%;" clearable filterable v-model="model" >
<el-option
v-for="item in options"
:key="item.dataCode"
:label="item.dataCode"
:value="item.dataValue">
</el-option>
</el-select>
</template>
<script setup>
import {useLoadData} from "@/uses/useLoadData";
const model=defineModel();
const props=defineProps({
dictKey: {
type: String,
default: ""
}
})
let param = {
dictKey: props.dictKey,
};
const {data:options}= useLoadData("/dictItem/list",param);
</script>
<style scoped>
</style>
通过上面的代码,我们可以看到 const model = defineModel();
的用法。这里的 model
就相当于我们之前手动创建的 inputValue
,但它更加灵活和通用。
defineModel()
的优势
- 简化代码 :使用
const model = defineModel();
可以减少重复的代码,使得代码更加简洁清晰。 - 更好的组织代码 :将
v-model
的处理逻辑统一到一个地方,便于维护和管理。 - 灵活性 :
defineModel()
可以处理任意类型的输入,包括表单输入、复杂组件等。
示例:自定义输入框组件
下面是一个简单的示例,展示如何使用 const model = defineModel();
创建一个自定义的输入框组件,并添加了一些自定义的逻辑:
javascript
<template>
<input
:value="model"
@input="handleInput"
@blur="handleBlur"
/>
</template>
<script setup>
import { defineModel } from 'vue';
const model = defineModel();
// 处理输入事件
const handleInput = (event) => {
const newValue = event.target.value.toUpperCase(); // 将输入值转换为大写
model.value = newValue;
};
// 处理失焦事件
const handleBlur = () => {
console.log('Input blurred');
};
</script>
在这个示例中,我们使用 const model = defineModel();
来简化双向绑定,同时添加了自定义的输入处理逻辑和失焦处理逻辑。
总体来说,const model = defineModel();
是一个非常方便的工具函数,能够帮助我们更好地处理 v-model
,简化代码,提高开发效率。在实际开发中,可以根据需要结合自定义逻辑,更灵活地处理表单输入和其他交互操作。