Strage Vue行为。 V-if不能正常观看

时间:2017-10-20 07:06:23

标签: javascript vue.js frontend

我有一个非常奇怪的问题。我有简单的服务和vue组件。在模板中我有v-if监视服务变量(如果它是真的 - 应该显示div,否则不应该)。它在我使用赋值的布尔值定义变量时有效,但在变量未定义时则不起作用。我的方法isOpened()无论如何都将它计算为boolean,所以我不明白为什么这段代码不能正常工作。也许下面的代码可以更好地解释这个问题:

<template>
    <div id="communicate" v-if="service.isOpened()">
        This should display if 'f' property in service is true
    </div>
</template>

<script lang="ts">
import Vue from 'vue';
import Component from 'vue-class-component';

class OtherService {
    private f:boolean = false; //works, div is displayed with this line uncommented
    //private f:boolean; // f is undefined - does not work with this line uncommented

    public info(foo:string) { this.f = true; }
    public isOpened() { return (this.f === true) } //f is evaluated to bool anyway so it should not be any difference 
}
export default {
    name: 'component',
    data: function() {
        return {
            service: new OtherService()
        }
    },
    mounted: function() {
        console.log(this.service.isOpened()) //prints always false - ok
        setTimeout(() => {
            this.service.info('setting f to true') // f is set to true
            console.log(this.service.isOpened()) // prints true, div should display.
        }, 2000)
    }
};

1 个答案:

答案 0 :(得分:2)

这是因为TypeScript在没有值的情况下转换类属性的方式。

考虑两个类:

class ClassA {
    private myProperty: boolean;
}

class ClassB {
    private myProperty: boolean = false;
}

在ClassA中,我们定义了TypeScript知道的属性。在ClassB中,我们定义一个TypeScript知道的属性AND赋值。

在ES5中,这些转化为以下内容:

var ClassA = (function () {
    function ClassA() {
    }
    return ClassA;
}());

var ClassB = (function () {
    function ClassB() {
        this.myProperty = false;
    }
    return ClassB;
}());

很容易看到,只有在分配值后才会创建此属性。没有它,Vue无法知道这个属性是否存在。

如果你看一下vuejs.org的指南,就会有一个关于反应性的部分。

  

由于现代JavaScript的限制(以及放弃Object.observe),Vue无法检测属性添加或删除。由于Vue在实例初始化期间执行getter / setter转换过程,因此数据对象中必须存在一个属性,以便Vue转换它并使其具有反应性。