首页 > 解决方案 > Vue、TypeScript 无法调用组件方法

问题描述

我对 Vue 还是很陌生,我在解决这个问题时遇到了麻烦。从我能找到的所有代码示例中,我的代码看起来应该可以工作。

我已经定义了一个这样的组件:

<template>
    <div class="row">
        <div id="site-header">
            <img v-bind:src="headerImgUrl" alt="hero-image">
            <div class="hero-text strokeme">Some Hero Text</div>
        </div>

    </div>
</template>

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

    const bgimages = [
        { url: require('../assets/hero/hero1.png') },
        { url: require('../assets/hero/hero2.png') },
        { url: require('../assets/hero/hero3.png') },
        { url: require('../assets/hero/hero4.png') },
        { url: require('../assets/hero/hero5.png') },
        { url: require('../assets/hero/hero6.png') },
        { url: require('../assets/hero/hero7.png') },
        { url: require('../assets/hero/hero8.png') },
        { url: require('../assets/hero/hero9.png') },
        { url: require('../assets/hero/hero10.png') },
        { url: require('../assets/hero/hero11.png') },
        { url: require('../assets/hero/hero12.png') },
        { url: require('../assets/hero/hero13.png') },
        { url: require('../assets/hero/hero14.png') },
    ];

    @Component({
        data() {
            console.log(this.getHeaderImageUrl());
            return {
                headerImgUrl: bgimages[0].url,
            };
        },
        methods: {
            getHeaderImageUrl(): string {
                const min = Math.ceil(1);
                const max = Math.floor(14);
                const i = Math.floor(Math.random() * (max - min + 1)) + min;
                return bgimages[i].url;
            },
        },
    })
    export default class Home extends Vue { }
</script>

<style lang="scss">
    #site-header {
        position: relative;
        margin-bottom: 2em;
    }
    .hero-text {
        font-family: 'Patua One', cursive;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        font-size: 6em;
        font-weight: 800;
        text-align: center;
        color: #000;
    }
    .strokeme {
        text-shadow: -1px -1px 0 #fff, 1px -1px 0 #fff, -1px 1px 0 #fff, 1px 1px 0 #fff;
    }
</style>

但是,编译时出现错误:

错误 TS2339 (TS) 属性“getHeaderImageUrl”在类型“Vue”上不存在。

我该如何设置它以便它可以调用它自己的方法?还有一种更好的方法可以将随机 url 放入图像源中吗?

或者,我将如何data.headerImgUrlgetHeaderImageUrl()方法内部更新?

如果我试试这个:

methods: {
    getHeaderImageUrl() {
        const min = Math.ceil(1);
        const max = Math.floor(14);
        const i = Math.floor(Math.random() * (max - min + 1)) + min;
        //return bgimages[i].url;
        this.headerImgUrl = bgimages[i].url;
    },
},

它错误:

错误 TS2339 (TS) 属性“headerImgUrl”在类型“Vue”上不存在。

我显然仍然没有得到某些东西的范围,或者配置了一些错误的东西,因为这似乎是非常基本的东西。

更新

所以我像这样重写了我的组件:

<template>
    <div class="row">
        <div id="site-header">
            <img v-bind:src="headerImgUrl" alt="hero-image">
            <div class="hero-text strokeme">Some Hero Text</div>
        </div>
    </div>
</template>

<script lang="ts">
    import Vue from 'vue';

    const bgimages = [
        { url: require('../assets/hero/hero1.png') },
        { url: require('../assets/hero/hero2.png') },
        { url: require('../assets/hero/hero3.png') },
        { url: require('../assets/hero/hero4.png') },
        { url: require('../assets/hero/hero5.png') },
        { url: require('../assets/hero/hero6.png') },
        { url: require('../assets/hero/hero7.png') },
        { url: require('../assets/hero/hero8.png') },
        { url: require('../assets/hero/hero9.png') },
        { url: require('../assets/hero/hero10.png') },
        { url: require('../assets/hero/hero11.png') },
        { url: require('../assets/hero/hero12.png') },
        { url: require('../assets/hero/hero13.png') },
        { url: require('../assets/hero/hero14.png') },
    ];

    export default Vue.extend({
        computed: {
            headerImgUrl() {
                return this.getHeaderImageUrl();
            },
        },
        methods: {
            getHeaderImageUrl() {
                const min = Math.ceil(1);
                const max = Math.floor(14);
                const i = Math.floor(Math.random() * (max - min + 1)) + min;
                console.log(1);
                return bgimages[i].url;
            },
        },
    });

</script>

<style lang="scss">
...
</style>

但是我仍然遇到无法访问该方法的错误:

错误 TS2339 (TS) 属性“getHeaderImageUrl”在类型“CombinedVueInstance>>”上不存在。

标签: typescriptvue.js

解决方案


您实际上结合了两种不同的方法来创建一个组件。这里有两个例子:

使用“vue-property-decorator”:

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

@Component()
export default class HelloDecorator extends Vue {

    @Prop(type: String, default: "")
    name: string;

    @Prop({ type: Number, default: 1 })
    initialEnthusiasm: number;

    enthusiasm = this.initialEnthusiasm;

    increment() {
        this.enthusiasm++;
    }

    decrement() {
        this.enthusiasm--;
    }

    get exclamationMarks(): string {
        return Array(this.enthusiasm + 1).join('!');
    }
} 

使用扩展:

import Vue from "vue";
export default Vue.extend({
    props: {
        name: {
            type: String,
            default: ""
        },
        enthusiasmLevel: {
            type: Number,
            default: 1
        }
    },
    computed: {
        helloMessage() {
            return "Hello " + this.name + this.getExclamationMarks(this.enthusiasmLevel);
        }
    },
    methods: {
        getExclamationMarks(numChars) {
            return Array(numChars + 1).join('!');
        },
        onDecrement() {
            this.$emit("onDecrement");
        },
        onIncrement() {
            this.$emit("onIncrement");
        }
    }
})

推荐阅读