【问题标题】:How to extend the prop typings of a native HTML element in Vue?如何在 Vue 中扩展原生 HTML 元素的属性类型?
【发布时间】:2021-12-22 15:22:48
【问题描述】:

假设我有一个元素,它包装了一个输入并获取了它的所有属性,此外还有一些属性。

在反应中,这将被键入

interface ExtendedInputProps extends React.ComponentPropsWithoutRef<'input'> {
    some: Type
}

这是一个非常常见的用例。我知道 Vue 3 根据传递给 defineComponent 中 props: 对象的任何内容生成其 prop 类型。

我正在想象做类似的事情:

props:{
    ...getComponentProps('input')
    additionalProp: String
}

但我不知道该怎么做,也找不到任何文档。有可能吗?

【问题讨论】:

  • 您是否尝试为打字稿类型检查做更多的事情,或者您不必手动/显式定义所有第二个对象属性?
  • 是的。如果你传入一个未识别的属性,vue 不会抛出运行时警告吗?我正在构建将用作库的一部分的组件。打字和用户体验需要很好,这不能是一个简陋的界面
  • 是的,我可以完全省略 props 并使用 defineComponent&lt;SomeInterface&gt; 上的类型参数/泛型设置 props 类型,但是 Vue 似乎阻止任何 props 实际到达我的组件,因为它们没有明确定义在运行时。
  • 我认为您不想将所有原生 input 属性声明为包装组件的道具,因为这需要您在模板或渲染函数中“手动”绑定它们。最好使用Non-Prop Attributes

标签: typescript vue.js vuejs3


【解决方案1】:

最简单的情况是当 input 是组件的根元素时,你不需要额外声明任何东西,只需将属性传递给你的组件,它们就会被传递下去

//NumberInput Component
<template>
    <input :value="modelValue"
      @input="$emit('update:modelValue', $event.target.value)"  />
</template>

<script setup lang="ts">
defineEmits(["update:modelValue"])
const props = withDefaults(defineProps<{
    modelValue?: number
}>(), { modelValue: 0 })
</script>

可以这样使用:

<number-input v-model="data" type="text" placeholder="123-45-678" />

其中typeplaceholder 最终将作为输入元素的属性。

如果你的组件中有嵌套的输入,你需要禁用属性继承:

//NumberInput Component
<template>
  <div class="wrapper">
    <input :value="modelValue" v-bind="$attrs" 
      @input="$emit('update:modelValue', $event.target.value)"  />
  </div>

</template>

<script setup lang="ts">
defineEmits(["update:modelValue"])
const props = withDefaults(defineProps<{
    modelValue?: number
}>(), { modelValue: 0 })
</script>

<script lang="ts">
// normal `<script>`, executed in module scope (only once)
// declare additional options
export default {
  inheritAttrs: false,
  customOptions: {}
}
</script>

请注意,我们添加了第二个脚本标记来禁用inheritAttrs,并添加v-bind="$attrs" 到输入以显式向下传递属性。有关该主题的更多信息,您可以找到here

【讨论】:

    猜你喜欢
    • 2019-02-09
    • 1970-01-01
    • 2020-07-29
    • 1970-01-01
    • 1970-01-01
    • 2019-02-06
    • 2019-10-30
    • 2016-10-23
    • 1970-01-01
    相关资源
    最近更新 更多