Vue,TypeScript无法调用组件方法

时间:2019-06-30 07:49:09

标签: typescript vue.js

我对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.headerImgUrl方法内部更新getHeaderImageUrl()

如果我尝试这样做:

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

1 个答案:

答案 0 :(得分:1)

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

使用“ 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");
        }
    }
})