vue3小知识之跨组件双向绑定

238 阅读1分钟

vue3中v-mode跨域组件的双向绑定

起因:我自己定义了一个组件,组件里面了使用了element-plus的组件,需要v-model传值,但是传的值也是在顶级组件传给我自己定义的这个组件。所以如果直接都使用v-model的话就打破了单项数据流,因此可以用v-model和computed的方式解决

useVModel函数:更通用

export function useVModel (props, propName, emit) {
  return computed({
    get () {
      return new Proxy(props[propName], {
        set (obj, name, val) {
          emit('update:' + propName, { ...obj, [name]: val })
          return true
        }
      })
    },
    set (val) {
      emit('updata:' + propName, val)
    }
  })
}

例子:

//父组件
  <SelectTest v-model="select_test_value"></SelectTest>


//子组件


const props = defineProps({
    modelValue:{type:Object,require:true}
})

const emit = defineEmits(['update:modelValue'])
const model = useVModel(props,modelValue,emit)

父组件

image.png

子组件

image.png

Ts中

1.get里面也可以改成上面一样的

export const useVModelInProp = <
  P extends Record<string, any>,
  K extends keyof P["modelValue"] & string
>(
  props: P,
  key: K,
  emit: (name: "update:modelValue", ...args: any[]) => void
) => {
  return computed<P["modelValue"][K]>({
    get: () => props.modelValue[key],
    set: (newValue) => {
      emit("update:modelValue", { ...props.modelValue, [key]: newValue });
    },
  });
};

2.这个对于单个数据更方便

export const useVModel = <
  P extends Record<string, any>,
  K extends keyof P & string,
  Name extends string
>(
  props: P,
  key: K,
  emit: (name: Name, ...args: any[]) => void
) => {
  return computed<P[K]>({
    get: () => props[key],
    set: (newValue) => emit(`update:${key}` as Name, newValue),
  });
};