typescript 如何在带有打字稿的 Vue.js 中使用计算道具

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/51982139/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 07:57:36  来源:igfitidea点击:

How to use computed props in Vue.js with typescript

typescriptvue.jsvuejs2

提问by Lev Khruschev

There're a lot of documentation how to interact with Vue.js using javascript language and just a little about typescript. The question is how to define computedprops in vuecomponent if it written on typescript. According the official examplecomputedis an object with functions which will be cached based on their dependent props. Here is an example I made:

有很多关于如何使用 javascript 语言与 Vue.js 交互的文档,并且只有一点关于打字稿。问题是如果组件写在打字稿上,如何computedvue组件中定义道具。根据官方示例computed是一个具有函数的对象,这些函数将根据它们的依赖道具进行缓存。这是我做的一个例子:

import Vue from 'vue';
import { Component } from "vue-property-decorator";

@Component({})
export default class ComputedDemo extends Vue {
    private firstName: string = 'John';
    private lastName: string = 'Doe';
    private computed: object = {
        fullName(): string {
            return `${this.firstName} ${this.lastName}`;
        },
    }
}

And html:

和 html:

<div>
    <h1>Computed props ts demo</h1>
    <ul>
        <li>First name: {{firstName}}</li>
        <li>Last name: {{lastName}}</li>
        <li>Together: {{fullName}}</li>
    </ul>
</div>

Third list item outputs nothing. Can anybody tell me how do define computedin this case, please?

第三个列表项不输出任何内容。有人能告诉我computed在这种情况下如何定义吗?

回答by Jeremy Walters

You can use property accessors to declare computed properties. See Vue Class Component. The getter will be triggered as soon as you type in the input.

您可以使用属性访问器来声明计算属性。请参阅Vue 类组件。只要您输入输入,getter 就会被触发。

For example:

例如:

<template>
    <div>
        <input type="text" name="Test Value" id="" v-model="text">

        <label>{{label}}</label>
    </div>

</template>

<script lang="ts">
import { Component, Vue, Watch } from "vue-property-decorator";

@Component({})
export default class About extends Vue {
    private text = "test";

    get label() {
        return this.text;
    }
}
</script>


Update for Vue Composition Api

Vue Composition Api 更新

<template>
  <div>
    <input type="text" name="Test Value" id v-model="text" />

    <label>{{label}}</label>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, computed } from "@vue/composition-api";

export default defineComponent({
  setup() {
    const text = ref("test");

    const label = computed(() => {
      return text.value;
    });

    return {
      text,
      label
    };
  }
});
</script>

回答by Badgy

Because of the circular nature of Vue's declaration files, TypeScript may have difficulties inferring the types of certain methods. For this reason, you may need to annotate the return type on methods like render and those in computed.

由于 Vue 声明文件的循环性质,TypeScript 可能难以推断某些方法的类型。出于这个原因,您可能需要在渲染和计算等方法上注释返回类型。

import Vue, { VNode } from 'vue'

const Component = Vue.extend({
  data () {
    return {
      msg: 'Hello'
    }
  },
  methods: {
    // need annotation due to `this` in return type
    greet (): string {
      return this.msg + ' world'
    }
  },
  computed: {
    // need annotation
    greeting(): string {
      return this.greet() + '!'
    }
  },
  // `createElement` is inferred, but `render` needs return type
  render (createElement): VNode {
    return createElement('div', this.greeting)
  }
})

If you find type inference or member completion isn't working, annotating certain methods may help address these problems. Using the --noImplicitAny option will help find many of these unannotated methods.

如果您发现类型推断或成员补全不起作用,注释某些方法可能有助于解决这些问题。使用 --noImplicitAny 选项将有助于找到许多这些未注释的方法。

More Info

更多信息