Vue.js使用计算属性来显示或隐藏组件的一部分

时间:2018-03-08 06:53:34

标签: javascript vuejs2 vue-component

我试图根据下拉列表中的值显示/隐藏组件的一部分。在移动我的表单的这一部分之前,使用计算属性工作得很好。但是...我在我的组件中使用双向绑定,似乎我正在使用的属性的计算值更新太晚了。这是组件js

Vue.component('system', {

    template: '#system',

    props: ['name', 'count'],

    computed: {
        issummit: function() {
            return this.name === '5a37fda9f13db4987411afd8';
        }
        // audiovideo: function() {
        //     return this.system === params.id.easy3eeg || this.system === params.id.easy3psg || this.system === params.id.essentia;
        // }
    },

    data () {
        return { 
            systemname: this.name,
            systemcount: this.count,
            systemoptions: [
                { text: 'Select One', value: null },
                { text: 'Summit', value:'5a37fda9f13db4987411afd8'},
                { text: 'Essentia', value:'5a37fda1de9e84bb9c44a909'},
                { text: 'Alterna', value:'5a8caadc86dc269de9887b0f'},
                { text: 'Easy III PSG', value:'5a37fe27b1e43d5ca589aee3'},
                { text: 'Easy III EEG', value:'5a37fd9a08a387d4efcf9ddb'},
                { text: 'IOMAX', value:'5a8cab59a1353f170f6e92a4'},
                { text: 'Cascade Pro', value:'5a8cab696f6a77f774e8de7f'}
            ]
        }
    },

    watch: {
        name (name) {
            this.systemname = name;
        },
        count (count) {
            this.systemcount = count;
        }
    },

    methods: {
        updateName: function() {
            this.$emit('update:name', this.systemname);
        },
        updateCount: function() {
            this.$emit('update:count', this.systemcount);
        }
    }
});

这是组件模板

    <script type="text/x-template" id="system">
        <b-row>
            <b-form-group class="col-sm" label="Count">
                <b-form-input type="number" @change="updateCount" required v-model="systemcount" class="col-sm"></b-form-input>
            </b-form-group>
            <b-form-group class="col-sm" label="System">
                <b-form-select @change="updateName" :options="systemoptions" required v-model="systemname"></b-form-select>
            </b-form-group>

            <!-- Summit Options -->
            <template v-if="issummit">
                <b-form-group class="col-sm" label="Channels">
                    <b-form-input type="number" required v-model="summitchannels"></b-form-input>
                </b-form-group>
                <b-form-group label="Accessories">
                    <b-form-checkbox-group v-model="summitaccessories" :options="summitoptions">
                    </b-form-checkbox-group>
                </b-form-group>
            </template> 

        </b-row>
    </script>
    <script src="scripts/system.js"></script>

这是正在使用的模板

<system v-for="system in systems"
    :name.sync="system.name"
    :count.sync="system.count">
</system>

计算出的值确实会更新......但问题是它在用于确定渲染后似乎更新了。如果我选择&#34; Summit&#34;在我的下拉菜单中,我希望我的组件的隐藏部分显示,直到我选择其他东西然后显示...第二次我做出选择时使用前一次尝试的计算值。

修改 根据一些建议我编辑了选择使用常规DOM对象,这解决了问题。然而,当我把它移到一个模板上时,这只会成为一个问题...之前所有的一切都很有意义......任何想法?

<div role="group" class="col-sm b-form-group form-group">
    <label class="col-form-label pt-0">System</label>
    <div>
        <select @change="updateName" class="form-control custom-select" required v-model="systemname">
            <option v-for="o in systemoptions" :value="o.value">{{o.text}}</option>
        </select>
    </div>
</div>

3 个答案:

答案 0 :(得分:3)

我在https://jsfiddle.net/3vkqLnxq/1/

中进行了极少的复制

按预期工作。更改后,所有b-*标记都更改为dom。

所以最可能的原因是b-form-select有一些问题。

答案 1 :(得分:3)

您应该使用getter和setter来计算绑定的计算属性数据。

这样的事情:

computed: {
  issummit: {
    // getter
    get: function () {
      return this.name === '5a37fda9f13db4987411afd8';
    },
    // setter
    set: function (newValue) {
      this.systemname = newValue;
    }
  }
}

更多:

https://v1.vuejs.org/guide/computed.html#Computed-Setter

答案 2 :(得分:1)

我通过更改

解决了类似的问题

@变化= “updateName”

@ change.native = “updateName”

https://vuejs.org/v2/guide/components.html#Binding-Native-Events-to-Components

这让我使用“真正的”直接变化事件(而不是太晚的事件)来解决我的问题。