useVModel.js
import { computed } from "vue";
export default function useVModle(props, propName, emit) {
return computed({
get() {
return new Proxy(props[propName], {
get(target, key) {
return Reflect.get(target, key)
},
set(target, key, newValue) {
emit('update:' + propName, {
...target,
[key]: newValue
})
return true
}
})
},
set(value) {
emit('update:' + propName, value)
}
})
}
组件使用
<!-- 父组件 -->
<template>
<div>
<my-component v-model="form"></my-component>
</div>
</template>
<script setup>
import myComponent from "./components/MyComponent.vue";
const form = ref({
name: "张三",
age: 18,
sex: "man",
});
watch(form, (newValue) => {
console.log(newValue);
});
</script>
<!-- 子组件 -->
<template>
<div>
<el-input v-model="form.name"></el-input>
<el-input v-model="form.age"></el-input>
<el-input v-model="form.sex"></el-input>
</div>
</template>
<script setup>
import useVModel from "../hooks/useVModel";
const props = defineProps({
modelValue: {
type: Object,
default: () => {},
},
});
const emit = defineEmits(["update:modelValue"]);
const form = useVModel(props, "modelValue", emit);
</script>