使用带有 TypeScript 的 Vue3 SFC 属性键入错误

Type errors using properties with Vue3 SFC with TypeScript

我很难尝试在 Vue3 中使用属性。我尝试了几种不同的方法,但它们都未能通过类型检查阶段(例如:yarn build)。

我的项目是使用Vite创建的一个全新的vue3-ts项目。这是我的组件:

<script lang="ts">
import { defineComponent } from 'vue'

export default defineComponent({
  name: "Test",
  props: {
    label: {
      type: String as PropType<string>,
      required: true,
    },
  },
  methods:  {
    onClick() {
      console.log(this.label);  // This line yields an error!
    },
  },
});
</script>

我得到一个 this.label 不存在的错误:Property 'label' does not exist on type 'CreateComponentPublicInstance<Readonly<ExtractPropTypes<Readonly<ComponentPropsOptions<Data>>>> & ...

volar 抱怨同样的事情)。

我尝试了几种不同的方法,但都没有更好的运气,这些是:


使用<script setup>方法定义道具:

<script setup lang="ts">
const props = defineProps({
  classes: String,
  label: String,
})
</script>

这也会对未使用的 props 变量发出警告。这没什么大不了的,但上面的错误仍然存​​在。


在我的组件上使用 setup 方法:

  setup(props) {

    defineProps({
      classes: String,
      label: String,
    })
  },

使用定义 props 的老派形式,对定义类型有点过分:

export default defineComponent({
  name: "AppStory",
  props: {
    label: {
      type: String as PropType<string>,
      required: true,
    },
  },

一种稍微不那么热心的方法:

export default defineComponent({
  name: "AppStory",
  props: {
    label: {
      type: String,
      required: true,
    },
  },

有人有使用属性的 Vue3 的 SFC 工作示例吗?我究竟做错了什么?我在那里发现的所有示例都没有道具,或者不使用 TS。 Vue'3 文档不是很以 TS 为中心,并且似乎没有示例涵盖这种(相当基本的)场景。

好吧,我默认使用 vue-ts 设置创建了一个新的 vite 应用程序,第一个示例中唯一缺少的是导入。 PropType 类型。

<template>
  <div>
    <button @click="onClick">{{ label }}</button>
  </div>
</template>
<script lang="ts">
import { defineComponent, PropType } from "vue";

export default defineComponent({
  name: "Test",
  props: {
    label: {
      type: String as PropType<string>,
      required: true,
    },
  },
  methods: {
    onClick() {
      console.log(this.label); // This line yields an error!
    },
  },
});
</script>

这是父组件(默认App.vue组件)

<script setup lang="ts">
// This starter template is using Vue 3 <script setup> SFCs
// Check out https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup
import HelloWorld from "./components/HelloWorld.vue";
</script>

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <HelloWorld label="Hello Vue 3 + TypeScript + Vite" />
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

这对我来说很好用。

现在是在脚本标记中使用 setup 关键字的相同示例:

<template>
  <div>
    <button @click="onClick">{{ label }}</button>
  </div>
</template>

<script lang="ts" setup>
import { PropType } from "vue";
const props = defineProps({
  label: {
    type: String as PropType<string>,
    required: true,
  },
});

const onClick = () => {
  console.log(props.label); // This line yields an error!
};
</script>

它也有效。

最后使用设置方法:

<template>
  <div>
    <button @click="onClick">{{ label }}</button>
  </div>
</template>

<script lang="ts">
import { defineComponent, PropType } from "vue";

export default defineComponent({
  name: "Test",
  props: {
    label: {
      type: String as PropType<string>,
      required: true,
    },
  },
  setup(props) {
    const onClick = () => {
      console.log(props.label); // This line yields an error!
    };
    return { onClick };
  },
});
</script>

希望这能解决您的问题。