【问题标题】:Vue 3 script setup prop validation typescriptVue 3 脚本设置道具验证打字稿
【发布时间】:2023-01-24 02:00:42
【问题描述】:

我正在尝试用打字稿中的 Vue 3 脚本设置语法替换我的 Vue 2 选项 API 道具对象代码。

现存的:

type: {
  type: String,
  default: 'button',
  validator: (prop) => ['button', 'submit', 'reset'].includes(prop)
}

到目前为止我有这个:

<script lang="ts" setup>
interface Props {
  type?: string;
}

const props = withDefaults(defineProps<Props>(), { type: 'button' });
</script>

但我找不到任何关于如何在脚本设置语法中处理道具验证器的信息

【问题讨论】:

    标签: typescript vuejs3


    【解决方案1】:

    您可以在 defineProps 中使用与 Options API 中相同的结构。 (DOCS)

    <script lang="ts" setup>
      type Type = 'button' | 'submit' | 'reset';
    
      interface Props {
        type: Type;
      }
    
      const props = defineProps<Props>({ 
        type: {
          type: String,
          default: 'button',
          validator: (prop: Type) => ['button', 'submit', 'reset'].includes(prop)
        }
      });
    </script>
    

    【讨论】:

    • 感谢您的选择! Vue3 和 Typescript 很新,但必须将每个道具定义 3 次是……疯狂的……
    • @泰坦。我不确定“定义道具 3 次”是什么意思。您只需要在&lt;script setup&gt; 或 Options API 中定义它们
    • type 在接口中应该是可选的,因为它在 defineProps 中有默认值;)
    • 当我不导出接口时,打字稿也会对我大喊“模块的默认导出具有或正在使用私有名称'Props'”:)
    • 无法摆脱:Type 'Props' does not satisfy the constraint 'ComponentObjectPropsOptions&lt;Data&gt;'. Index signature for type 'string' is missing in type 'Props'.ts(2344)?
    【解决方案2】:

    我相信我已经解决了,对打字稿来说仍然是新手,但这应该是等价的(将在打字稿而不是 vue 运行时进行验证)

    interface Props {
      type?: 'button' | 'submit' | 'reset';
    }
    

    【讨论】:

    • 打字稿验证的好主意。但是这个解决方案意味着,在运行时,将不会进行验证。
    • 对于大多数用例,这就足够了。 99% 的时间你会直接传递类型(即,不是从变量),如果你确实需要(举个例子)使用用户输入,验证应该发生在输入进来的地方,而不是在这里在组件中
    【解决方案3】:

    按照@Titan 的回答,我喜欢以一种可以直接访问脚本中的道具的方式来编写它。

    <script setup lang="ts">
    type Type = 'button' | 'submit' | 'reset';
    
    const { type } = withDefaults(defineProps<{
      type?: Type
    }>(),{
      type: 'button'
    })
    //As it is already deconstructed, you can use it as `type` instead of `props.type`
    </script>
    

    尽管我建议将 prop 名称从 type 更改为不同的名称,因为 typescript 可能会误解实际类型声明的 prop 名称。

    【讨论】:

    • 不错的版本,但前提是您不需要在某些父级中使用接口。所以@Orbis 的版​​本在这种情况下更好:)
    • 顺便说一句,道具在模板中自动可用,您根本不需要分配从 withDefaults 返回的值?
    【解决方案4】:

    对于那些同样来自 Google 的人,并且由于 Vue 文档对此不是很清楚,您也可以使用 Vue 2 样式选项格式进行直接转换:

    const props = defineProps({
      type: {
        type: String,
        default: 'button',
        validator: (prop) => ['button', 'submit', 'reset'].includes(prop)
      }
    })
    

    【讨论】:

      【解决方案5】:

      我最后得到了这个?‍♂️

      <script lang="ts" setup>
        import type { PropType } from 'vue';
        export type Type = 'button' | 'submit' | 'reset';
      
        export interface Props {
          type: Type;
        }
      
        defineProps({ 
          type: {
            type: String as PropType<Type>,
            default: 'button',
            validator: (prop: Type) => ['button', 'submit', 'reset'].includes(prop)
          }
        });
      </script> 
      

      【讨论】:

        【解决方案6】:

        您可以这样做以避免重复这些值。

        <script lang="ts" setup>
        const types = ['button' | 'submit' | 'reset'] as const
        export type Type = typeof types[number]
        
        const props = defineProps<Props>({ 
          type: {
            type: String as PropType<Type>,
            default: 'button',
            validator: (prop: Type) => types.includes(prop)
          });
        </script>
        

        【讨论】:

          猜你喜欢
          • 2021-10-25
          • 2018-09-07
          • 2022-11-28
          • 2021-11-04
          • 2022-08-14
          • 2020-12-26
          • 1970-01-01
          • 1970-01-01
          • 2022-12-12
          相关资源
          最近更新 更多