使用计算属性

时间:2017-08-04 07:54:22

标签: javascript json vue.js vuejs2

最初在我的Vue组件中,我有一系列嵌套的if语句,这些语句将通过JSON数据来确定是应该显示文本输入还是基于has_selectable_value选项为true的选择(选择显示)或者是假(文本输入显示),如果它是一个选择,则循环遍历数据和输出相关选项。

我已经能够将其更改为一个计算语句,除了显示选择选项之外,它几乎完成了我需要做的所有事情。

以下是Vue代码的相关部分:

<template v-else-if="searchtype == 9">
    <select v-for="service in selectableServices" class="form-control" v-model="searchvalue" required>
        <option value="">Select A Location</option>
        <option v-for="sl in selectableLocations" :value="sl.location_id">{{sl.name}}</option>
    </select>
    <input v-for="service in nonSelectableServices" class="form-control" v-model="searchvalue" placeholder="Enter Search Value" required>
</template>

当前计算的函数:

services: function () {   
    var ret = []
    this.countries.forEach(function(country) {
        country.states.forEach(function(state) {
            state.services.forEach(function(service) {
                ret.push(service)
            });
        });
    });

    return ret;               
},
selectableServices: function () {
    return this.services.filter(service => service.id == this.service && service.has_selectable_location);
},
nonSelectableServices: function () {
    return this.services.filter(service => service.id == this.service && !service.has_selectable_location);
},
selectableLocations: function () {
    // Filter one more level down
    return this.selectableServices.map(service => service.selectablelocations);
},

这也是我正在使用的JSON数据结构(我将其切换回这部分代码的相关部分):

[
    {
    "id": 1,
    "name": "Country Name",
    "states": [
        {
            "id": 1,
            "name": "State Name",
            "services": [
                    {
                    "id": 1,
                    "name": "Service Name",
                    "has_selectable_location": 1,
                    "selectablelocations": [
                            {
                                "id": 1,
                                "name": "Selectable Location A",
                            },
                        ]
                    }
                ]
            }
        ]
    }
]

使用Chrome的Vue插件我可以看到计算函数selectableLocations加载包含各个位置的数组,但现有的v-for语句无法正常运行。相反,我仍然需要通过添加一个额外的v-for循环来实现我可以做的更多级别:

<template v-for="selectableLocationsList in selectableLocations" >
    <option v-for="sl in selectableLocationsList"  :value="sl.location_id">{{sl.name}}</option>
</template>

一切都正确显示,但我不确定这是否是最佳实践,因为我希望在计算函数中尽可能多地执行此操作,理想情况下只需要一个v-for语句。但是,如果不可能像我理解的那样,我可以保持原样。

提前谢谢。

编辑:经过更多测试和研究后,我提出了这个代码,它可以按照我的意愿运行:

var formArray = []
var locationsArray = this.servicesArray.filter(service => service.id == this.service);

locationsArray.map(service => service.selectablelocations);

locationsArray.forEach(function(selectableLocations) {
    selectableLocations.selectablelocations.forEach(function(location) {
        formArray.push(location)
    });
});

return formArray;

有没有办法可以进一步重构这个并使它更清洁一点?

1 个答案:

答案 0 :(得分:0)

仅考虑您在修改之后发布的代码,代码可以通过以下方式重构:

let formArray = [];

formArray = this.servicesArray
  .filter(service => service.id == this.service)
  .map(service => service.selectablelocations)
  .reduce((prev, curr) => prev.concat(curr))

return formArray

请注意,您使用的map不会执行任何操作,因为Array.prototype.map只返回一个新数组,但您没有将其分配给任何内容。