vue3 + ts,prop使用PropType校验联合类型的问题?

李不太优秀
  • 7

问题描述

vue3 + ts;在props中使用PropType来验证数据,因为业务中需要自动遍历定义好的表单组件或slot组件,故分别为表单组件和slot组件定义了两个类型。PorpType中传入的类型正是是联合类型FormOptions | SlotOptions 组成的别名 FormItemFormOptions中定义的属性在SlotOptions中没有,vue模板上校验报错某某字段在SlotOptions上不存在,如图:
image.png

相关代码

interface

export interface FormOptions {
  readonly label: string;
  readonly name: string;
  readonly type: QuickCmp;
  config?: any;
  defaultValue?: any;
  unchecked?: boolean;
  rules?: any[];
  [key: string]: any;
}

export interface SlotOptions {
  slot: boolean;
}

export type FormItem = FormOptions | SlotOptions;

PropType

 props: {
    formOptions: {
      type: Array as PropType<FormItem[]>,
      required: true,
    }
}

父组件传入的数据

const formOptions: Array<FormItem> = [
  { label: '下拉框2', name: 'select2', type: QuickCmp.Select, defaultValue: [], config: { options: options, multiple: true, isGroup: true } },
  { label: '开关1', name: 'switch2', type: QuickCmp.Switch, defaultValue: false, config: {  } },
  { label: '日期1', name: 'date1', type: QuickCmp.Date },
  { slot: true },
  { label: '时间1', name: 'time1', type: QuickCmp.Time, config: { 'is-range': true } },
]

我大概知道原因了,可能是因为没有做类型守卫,可是不知道如何在模板中使用类型守卫😷😷😷
如何才能让vue模板识别联合类型,或者有什么其他解决方法嘛😥😥😥😥

回复
阅读 4.2k
1 个回答

花了两个小时瞎摸索,自己找到了方法😂,其实就是很普通的守卫方法
把模板上的 v-ifitem.slot 的校验方式换成 'slot' in item

<template v-for="item in formOptions" :key="item.name">
  <slot v-if="'slot' in item">这是插槽,未定义内容</slot>
  <el-form-item
    v-else
    :label="item.label"
    :prop="item.name"
    >
    <span v-if="item.inline" class="inline-text-left">{{ item.inline[0] }}</span>
    <component 
      v-model="defaultData[item.name]" 
      v-bind="item.config"
      :is="item.type" 
      />
      <span v-if="item.inline" class="inline-text-right">{{ item.inline[1] }}</span>
  </el-form-item>
</template>
宣传栏