v-model 是 vue3 中的一个内置指令,很多表单元素都可以使用这个属性,如 input、checkbox 等,咱可以在自定义组件中实现 v-model。v-model 本质上是一个语法糖:
理解了 v-model 的本质,咱可以分别使用 SFC(.vue 文件)和 TSX(.tsx)方式定义一个组件 person-name ,使该组件可以使用 v-model。
person-name 包括两个输入框,分别是“姓”(familyName)和“名”(firstName)两个字段,v-model 传递的数据格式为:
{ familyName: '张', firstName: '三' }
首先定义该类型 person-name-type.ts:
export interface PersonName { /** 姓 */ familyName?: string; /** 名 */ firstName?: string; }
编写 person-name.scss 样式文件,后面再两个组件中分别引入:
.person-name { .el-form-item { width: 200px; } }
person-name 组件实现逻辑比较简单:
创建组件文件 person-name-sfc.vue:
<template> <div class="person-name"> <el-form-item label="姓"> <el-input v-model="innerFamilyName" @input="onInput"></el-input> </el-form-item> <el-form-item label="名"> <el-input v-model="innerFirstName" @input="onInput"></el-input> </el-form-item> </div> </template> <script lang="ts" setup name="person-name-sfc"> import { PropType, ref, watch } from 'vue' import { PersonName } from './person-name-type' const props = defineProps({ modelValue: { type: Object as PropType<PersonName>, required: true, default: () => ({}) } }) const emits = defineEmits(['update:modelValue']) const innerFamilyName = ref('') const innerFirstName = ref('') watch(() => props.modelValue, (newVal) => { innerFamilyName.value = newVal?.familyName || '' innerFirstName.value = newVal?.firstName || '' }, { deep: true, immediate: true }) const onInput = () => { emits('update:modelValue', { familyName: innerFamilyName.value, firstName: innerFirstName.value }) } </script> <style scoped lang="scss"> @import "./person-name"; </style>
创建组件文件 person-name-tsx.tsx:
import { defineComponent, PropType, ref, watch } from 'vue' import { PersonName } from './person-name-type' import './person-name.scss' export default defineComponent({ name: 'person-name-tsx', props: { modelValue: { type: Object as PropType<PersonName>, required: true, default: () => ({}) } }, emits: ['update:modelValue'], setup (props, context) { const innerFamilyName = ref(props.modelValue.familyName) const innerFirstName = ref(props.modelValue.firstName) const onInput = () => { context.emit('update:modelValue', { familyName: innerFamilyName.value, firstName: innerFirstName.value }) } watch(() => props.modelValue, (newVal) => { innerFamilyName.value = newVal?.familyName || '' innerFirstName.value = newVal?.firstName || '' }, { deep: true, immediate: true }) return () => ( <div class="person-name"> <el-form-item label="姓"> <el-input vModel={innerFamilyName.value} onInput={onInput}/> </el-form-item> <el-form-item label="名"> <el-input vModel={innerFirstName.value} onInput={onInput}/> </el-form-item> </div> ) } })
创建父组件 demo-v-model.vue,在里面使用上面定义的两个组件:
<template> <div> <person-name-sfc v-model="personName1"></person-name-sfc> <el-button @click="onResetClick1">reset</el-button> <div>{{personName1}}</div> </div> <el-divider /> <div> <person-name-tsx v-model="personName2"></person-name-tsx> <el-button @click="onResetClick2">reset</el-button> <div>{{personName2}}</div> </div> </template> <script lang="ts" setup> import PersonNameSfc from '@/components/model/person-name-sfc.vue' import { ref } from 'vue' import { PersonName } from '@/components/model/person-name-type' import PersonNameTsx from '@/components/model/person-name-tsx' const defaultPersonName = { familyName: '张', firstName: '三' } const personName1 = ref<PersonName>({ ...defaultPersonName }) const personName2 = ref<PersonName>({ ...defaultPersonName }) const onResetClick1 = () => { personName1.value = { ...defaultPersonName } } const onResetClick2 = () => { personName2.value = { ...defaultPersonName } } </script>
标签:icode9,model,内置指令,数据,编写,Java 来源:
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。