vue3 自定义useVModel函数
vue3 中使用v-model 父子组件共享数据的方法:
前提知识点:
1、子组件中获取v-model的值:
const props = defineProps({
modelValue: {
type: Object,
required: true,
},
});
2、子组件中触发父组件修 改modelValue的方法,这是vue3内部方法,不需要在父组件中监听
const emit = defineEmits(['update:modelValue']);
emit('update:modelValue',newValue)
父组件代码:
<script setup>
import { onMounted, reactive, ref } from 'vue';
import AboutView from './AboutView.vue'
const chartContainer = ref(null)
const person = ref({name:'zs', age:20})
</script>
<template>
<div>
父组件修改共享数据名字:<input v-model="person.name"/>
</div>
<div>
父组件修改共享数据年龄:<input v-model="person.age"/>
</div>
<AboutView v-model="person"></AboutView>
</template>
//父组件使用v-model给子组件共享了一个对象
子组件代码:
<template>
<div class="about">
子组件数据:
{{ pdata.name }}
{{ pdata.age }}
{{ pdata }}
子组件修改父组件的名字:<input v-model="pdata.name" />
子组件修改父组件的年龄:<input v-model="pdata.age" />
</div>
</template>
<script setup>
import { getCurrentInstance, computed } from 'vue';
const _this = getCurrentInstance().proxy;
const props = defineProps({
modelValue: {
type: Object,
required: true,
},
});
const emit = defineEmits(['update:modelValue']);
function useVModel(props,propsName, emit) {
return computed({
get() {
// 使用 new Proxy 来创建代理对象
return new Proxy(props[propsName], {
get(target, key, receiver) {
return Reflect.get(target, key, receiver);
},
set(target, key, value){
// 当属性被修改时,触发事件将修改后的数据传回父组件
emit(`update:${propsName}`, { ...target, [key]: value });
return true;
},
});
},
//如果modelValue是一个对象,且子组件的去修改的是一个属性值,是触发不了set方法的,所以在get方法中使用 proxy代理进行了拦截
set(value) {
// 如果需要手动设置整个对象的值
emit(`update:${propsName}`, value);
},
});
}
const pdata = useVModel(props,'modelValue',emit)
</script>