父
<script setup lang="ts">
import { ref } from 'vue'
import HelloWorld from './components/HelloWorld.vue'
const searchData = ref({
keyword: '1',
optionList: ['1','2','3'],
value: ''
})
</script>
<template>
{{ searchData.value }}
<HelloWorld v-model="searchData" />
</template>
<style scoped>
子
<script setup lang="ts">
import { computed } from 'vue'
const props = withDefaults(
defineProps<{
modelValue: any,
name: string
}>(),
{
name: '张珊',
modelValue: ()=> {
keyword: ''
optionList: []
value: ''
}
}
)
const emit = defineEmits(['update:modeValue'])
const model = computed({
get(){
return new Proxy(props.modelValue,{
set(obj,name,val){
emit('update:modeValue',{
...obj,
[name]: val
})
return true
}
})
},
set(val){
emit('update:modeValue', val)
}
})
</script>
<template>
<div>
<select v-model="modelValue.keyword" style="width: 50px;">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<input type="text" v-model="modelValue.value" >
</div>
</template>
继续拆分
// useModel.ts
import { computed } from 'vue'
export function useModel(props:any, propName:string, emit:any){
return computed({
get(){
return new Proxy(props[propName],{
set(obj,name,val){
emit('update:'+propName,{
...obj,
[name]: val
})
return true
}
})
},
set(val){
emit('update:'+propName, val)
}
})
}
而后简化
<script setup lang="ts">
import { useModel } from './useModel'
const props = withDefaults(
defineProps<{
modelValue: any,
name: string
}>(),
{
name: '张珊',
modelValue: ()=> {
keyword: ''
optionList: []
value: ''
}
}
)
const emit = defineEmits(['update:modeValue'])
const model = useModel(props, 'modeValue', emit)
</script>
<template>
<div>
<select v-model="modelValue.keyword" style="width: 50px;">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<input type="text" v-model="modelValue.value" >
</div>
</template>
<style scoped>
.read-the-docs {
color: #888;
}
</style>