1 v-model
1.1 理解 v-model
v-model 是 vue3 中的一個內置指令,很多表單元素都可以使用這個屬性,如 input、checkbox 等,咱可以在自定義組件中實作 v-model,v-model 本質上是一個語法糖:
- 系結父組件傳遞過來的 modelValue 屬性;
- 值改變時向父組件發出事件 update:modelValue,
1.2 案例描述
理解了 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;
}
1.3 撰寫樣式
撰寫 person-name.scss 樣式檔案,后面再兩個組件中分別引入:
.person-name {
.el-form-item {
width: 200px;
}
}
2 撰寫組件
2.1 實作思路
person-name 組件實作邏輯比較簡單:
- template 中放置兩個輸入框 el-input,分別對應 姓 和 名 兩個欄位;
- 定義兩個變數 innerFamilyName 和 innerFirstName 系結兩個輸入框的值;
- 在 props 定義 modeValue 屬性,接收父組件傳遞過來的 PersonName 型別的物件;
- 使用 watch 深度監聽 modelValue,當其屬性值有變化時,重新賦值給上面系結輸入框的兩個變數;
- 當兩個輸入框觸發 input 事件時,通過 update:modelValue 事件通知父組件,從而實作 v-model,
2.2 SFC(.vue)中的實作
創建組件檔案 person-name-sfc.vue:
<template>
<div >
<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 = https://www.cnblogs.com/youyacoder/archive/2022/10/21/newVal?.familyName ||''
innerFirstName.value = https://www.cnblogs.com/youyacoder/archive/2022/10/21/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>
2.3 TSX(.tsx)中的實作
創建組件檔案 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 = https://www.cnblogs.com/youyacoder/archive/2022/10/21/newVal?.familyName ||''
innerFirstName.value = https://www.cnblogs.com/youyacoder/archive/2022/10/21/newVal?.firstName ||''
}, {
deep: true,
immediate: true
})
return () => (
<div >
<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>
)
}
})
3 使用組件
創建父組件 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 = https://www.cnblogs.com/youyacoder/archive/2022/10/21/{ ...defaultPersonName }
}
const onResetClick2 = () => {
personName2.value = { ...defaultPersonName }
}
</script>
運行效果如下:
上面部分使用 .vue 撰寫的組件,下面部分使用 .tsx 撰寫的組件,兩者獨立系結 v-model,運行效果完全一致,
- 子組件可以接收到父組件傳遞的初始值;
- 子組件值改變時會通知到父組件;
- 父組件改變值時,子組件會回應變更,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/518896.html
標籤:其他
上一篇:CesiumJs 簡單操作模型
下一篇:記錄--vue列印插件
