Vue2 vModel
- value
- input/change/select
Vue3 vModel 默认
- modelValue
- update:modelValue
常见的封装组件 通过v-model V2
<Demo v-model="test" :changeTest="changeTest" />
Demo.vlue
props:{test}
emit('changeTest')
V3
const data = ref({
name:"",
age:"",
})
<HelloWorld v-model="data" />
//Hellow.vue
<script setup>
import { ref, defineProps } from "vue";
const props = defineProps({
modelValue: {
type: Object,
default:()=> {}
}
})
</script>
<template>
<input type="text" v-model="props.modelValue.name" placeholder="姓名" />
<input type="text" v-model="props.modelValue.age" placeholder="年龄" />
</template>
看似V3这样可以实现 但是破坏了单向数据流 可以在computed中拦截
<FormModel v-model="data" />
useModel.js
import { computed } from 'vue';
export function useModel(props,propName,emit){
const model = computed({
get: () => {
return new Proxy(props[propName], {
get(target, key) {
console.log("get");
return Reflect.get(target, key)
},
set(target, key, value) {
emit('update:'+propName, {
...target,
[key]: value
})
return true
}
})
},
set: (val) => {
emit('update:'+propName,val)
return true
}
})
return model
}
<script setup>
import { ref, defineProps, computed,toRefs } from "vue";
import { useModel } from './../hooks/useModel';
const props = defineProps({
modelValue: {
type: Object,
default: () => { }
}
})
const emit = defineEmits(['update:modelValue'])
const model = useModel(props,"modelValue",emit)
</script>
<template>
<input type="text" v-model="model.name" placeholder="姓名" />
<input type="text" v-model="model.age" placeholder="年龄" />
</template>
<style scoped></style>
这也是VueUse中的 useVModels的实现原理