useVModel.ts
import { computed, WritableComputedRef } from 'vue'
export function useVModel<T>(
props: { [x: string]: any },
propName: string,
emit: (...args: any[]) => void,
): WritableComputedRef<T> {
return computed({
get() {
if (Object.prototype.toString.call(props[propName]) === '[object Object]') {
return new Proxy(props[propName], {
set(obj, name, val) {
emit(`update:${propName}`, Object.assign(obj, { [name]: val }))
return true
},
})
}
return props[propName]
},
set(val) {
emit(`update:${propName}`, val)
},
})
}
modelValue非对象使用方法
<template>
<Switch v-model="model" />
</template>
<script lang="ts" setup>
import {
defineEmits, defineProps,
} from 'vue'
import { Switch } from 'xxxxx'
import { useVModel } from '~/hooks/useVModel'
const emit = defineEmits(['update:modelValue'])
const props = defineProps({
modelValue: {
type: Boolean,
default: false,
require: true,
},
})
const model = useVModel<any>(props, 'modelValue', emit)
</script>
modelValue对象使用方法
<template>
<div class="account-business">
<Form ref="$refs">
<Field
name="accountScene"
required
:rules="[{ required: true, message: '此项必填' }]"
>
<template #input>
<AccountSelectType
v-model="model.accountScene"
:types-list="serviceList"
/>
</template>
</Field>
</Form>
</div>
</template>
<script setup lang="ts">
import {
ref, defineEmits, defineProps, PropType,
} from 'vue'
import { Form, Field } from 'xxxxx'
import { useVModel } from '~/hooks/useVModel'
import AccountSelectType from './AccountSelectType.vue'
import {
ACCOUNT_FORMVALUE, IAccountServiceItem,
} from '~/services/xxxxxx'
const props = defineProps({
modelValue: {
type: Object as PropType<ACCOUNT_FORMVALUE>,
required: true,
},
serviceList: {
type: Array as PropType<IAccountServiceItem[]>,
default: () => ([]),
},
})
const $refs = ref()
const emit = defineEmits(['update:modelValue'])
const model = useVModel<props的数据类型>(props, 'modelValue', emit)
defineExpose({ $refs })
</script>