【问题标题】:Vue.js 3: props type validation with custom typeVue.js 3:使用自定义类型验证道具类型
【发布时间】:2021-01-27 05:14:28
【问题描述】:

我正在使用 Vue.js 3 和 Typescript 开发单页应用程序。

该问题会影响视图和单个文件组件。 People.vue 从后端检索数据并使用v-for 将其显示在多个PersonRow.vue 组件中。尽管明确定义了数据属性类型,但我在浏览器控制台中收到警告:
[Vue warn]: Invalid prop: Type check failed for prop "person". Expected Person, got Object

一切正常,我可以将PersonRow.vue 中的属性类型更改为Object 以消除警告,但我希望类型检查正常工作。

People.vue

<template>
  <div class="container">
    <PersonRow v-for="person in people" :key="person.id" :person="person" />
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import { Person, getPeople } from '../services/person'
import PersonRow from '@/components/PersonRow.vue'

export default defineComponent({
  components: {
    PersonRow
  },
  data () {
    return {
      people: new Array<Person>()
    }
  },
  mounted () {
    getPeople().then(
      response => {
        this.people.push(...response)
      })
  }
})
</script>

PersonRow.vue

<template>
  <div class="row">
    <div class="col">{{ person.givenName }}</div>
    <div class="col">{{ person.familyName }}</div>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import { Person } from '../services/person'

export default defineComponent({
  props: {
    person: {
      type: Person,
      required: true
    }
  }
})
</script>

person.ts

export class Person {
  constructor (id: number, givenName: string, familyName: string) {
    this.id = id
    this.givenName = givenName
    this.familyName = familyName
  }

  id: number;
  givenName: string;
  familyName: string;
}

export async function getPeople (): Promise<Person[]> {
  const response = await fetch('https://api.example.com/people')
  return await response.json() as Person[]
}

【问题讨论】:

    标签: typescript vue.js vue-component vuejs3


    【解决方案1】:

    “人”不是一种类型。类型可以是数组、对象、字符串、数字、布尔值、函数。所以类型检查工作正常。

    【讨论】:

    • 文档声明自定义类型是可能的:v3.vuejs.org/guide/component-props.html#type-checks
    • 但它们的意思是 JavaScript 类。如果您的 TypeScript 类在构建时被转译,对于 Vue,它只是运行时的 Object(当 prop 类型检查发生时)
    • 还有文档说 验证 author 属性的值是用 new Person 创建的 但是你的 getPeople 函数没有调用 Person 构造函数,它只是将从 JSON 反序列化的常规 JS 对象转换为 Person[]
    • 感谢您提及。 PropType&lt;T&gt; 允许我将类型定义从 class 更改为 interface,这消除了未使用的构造函数的所有开销,同时类型推断和验证仍在工作。
    【解决方案2】:

    Annotating Props

    export default defineComponent({
      props: {
        person: {
          type: Object as PropType<Person>,
          required: true
        }
      }
    })
    

    深潜

    是的,docs 说:此外,type 也可以是自定义构造函数,并且断言将通过instanceof 检查进行

    但为了使其工作,传递给 prop 的对象必须使用 new Person() 构造函数创建。问题是您的getPeople () 函数没有创建Person 实例的数组 - 它只是将使用json() 创建的常规JS 对象的类型转换数组Person[]。类型转换不会改变对象的运行时类型...

    【讨论】:

      猜你喜欢
      • 2019-04-05
      • 2022-12-11
      • 1970-01-01
      • 2014-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-26
      • 1970-01-01
      相关资源
      最近更新 更多