【问题标题】:Type errors using properties with Vue3 SFC with TypeScript使用带有 TypeScript 的 Vue3 SFC 的属性键入错误
【发布时间】:2022-01-19 14:16:55
【问题描述】:

我在尝试将属性与 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&lt;Readonly&lt;ExtractPropTypes&lt;Readonly&lt;ComponentPropsOptions&lt;Data&gt;&gt;&gt;&gt; &amp; ...

volar 抱怨同样的事情)。

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


使用&lt;script setup&gt; 方法定义道具:

<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 为中心,似乎没有任何示例涵盖这种(相当基本的)场景。

【问题讨论】:

    标签: typescript vue.js vue-component


    【解决方案1】:

    好吧,我默认使用 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>
    

    它也有效。

    最后使用setup方法:

    <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>
    

    希望这能解决您的问题。

    【讨论】:

    • 我在复制粘贴样本时错过了 PropType 的导入,但我确实拥有它。您的示例无法为我构建:paste.sr.ht/~whynothugo/… 我将storybook 安装到我的示例环境中,也许这搞砸了,我会再试一次。
    • 是的,仅仅在环境中运行npx sb init 会以项目不再构建的方式弄乱依赖关系。感谢您的回复,如果没有您的反馈,我不会想到这一点。
    • 很高兴知道,欢迎!
    猜你喜欢
    • 1970-01-01
    • 2017-12-14
    • 2020-12-20
    • 2017-12-13
    • 2020-09-10
    • 2021-08-22
    • 2021-08-05
    • 2020-10-07
    • 1970-01-01
    相关资源
    最近更新 更多