使用 Vue3 的useVModel函数实现双向绑定

195 阅读1分钟

Vue3中,双向绑定是组件开发的重要特性。它允许父组件和子组件之间更高效的状态同步。借助 Composition API,我们可以灵活地实现这一功能。本文将讨论一个自定义的 useVModel 函数的实现,该函数可以处理单个属性或多个属性的双向绑定。

<!-- 父组件 -->
<UserInfoEditor v-model:name="name" v-model:age="age" />
<!-- 子组件 -->
<template>
    <input v-model="_name" />
    <input v-model="_age" />
</template>
<script setup lang="ts" >
import { useVModel } from 'xxx'
interface PropsType {
  name: string
  age: string
}
const props = defineProps<PropsType>()
const emit = defineEmits(['update:name', 'update:age'])
const [_name, _age] = useVModel(['name', 'age'])

</script>
//useVModel
import { getCurrentInstance, computed, type WritableComputedRef } from 'vue'
type KeysType = string | string[]
type VModelComputedType<T> = T extends string
  ? WritableComputedRef<any>
  : WritableComputedRef<any>[]
export function useVModel<T extends KeysType>(keys: T): VModelComputedType<T> {
  const instance = getCurrentInstance()
  const createComputed = (key: string) =>
    computed({
      get: () => instance?.props[key],
      set: (value: any) => instance?.emit(`update:${key}`, value),
    })
  if (Array.isArray(keys)) {
    return keys.map(createComputed) as any
  }
  return createComputed(keys) as any
}