【发布时间】:2021-08-02 13:26:12
【问题描述】:
我是新手,所以也许这是设计使然,但以防万一。 我有一个组件,它采用 facets 列表,然后将它们拆分为一个漂亮的显示。 代码如下所示:
import { getFacets } from "@/logic/get-facets";
import {
defineComponent,
getCurrentInstance,
ref,
toRefs,
} from "@vue/composition-api";
import Filters from "@/components/filters/filters.component.vue";
export default defineComponent({
name: "Chooser",
components: { Filters },
emits: ["onFilter"],
props: {
categoryName: {
type: String,
required: true,
},
facets: {
type: Array,
required: true,
},
loading: {
type: Boolean,
default: () => false,
},
},
setup(props) {
const instance = getCurrentInstance();
const expanded = ref(false);
const filters = ref([]);
const scenarios = ref([]);
const { facets } = toRefs(props);
const { criteria } = getFacets(facets.value);
const expand = () => {
expanded.value = !expanded.value;
};
const addFilter = (attribute: any) => {
let index = -1;
for (let i = filters.value.length - 1; i >= 0; i--) {
const filter = filters.value[i];
if (filter.facetName !== attribute.facetName) continue;
index = i;
filters.value.splice(i, 1);
}
if (index === -1) filters.value.push(attribute);
instance.proxy.$emit("onFilter", filters.value);
};
return { expanded, criteria, filters, scenarios, expand, addFilter };
},
});
getFacets 方法如下所示:
import { ref } from "@vue/composition-api";
class Facet {
key: string;
value: FacetItem[];
}
class FacetItem {
facetName: string;
count: number;
value: string;
from: string;
to: string;
}
export function getFacets(facets: any) {
const criteria = ref([]);
const facet = facets.find((item: Facet) => item.key === "Criteria/Attribute");
let currentCriterionName = "";
let criterion: any = {};
let count = 0;
(<Facet>facet).value
.sort((a, b) => a.value.localeCompare(b.value))
.forEach((item: FacetItem) => {
const value = item.value;
const [c, a] = value.split(":");
if (c !== currentCriterionName) {
if (criterion.name) criteria.value.push(criterion);
criterion = {
name: c,
attributes: [],
active: false,
};
currentCriterionName = c;
}
criterion.attributes.push({
name: a,
facetName: value,
to: item.to,
from: item.from,
count: item.count,
});
count++;
});
if (count === facet.value.length) criteria.value.push(criterion);
return { criteria };
}
如您所见,我的组件需要一个必需的 facets 数组(以及 categoryName 和可选的加载布尔值)。 初始数组如下所示:
[
{
"key":"Criteria/Attribute",
"value":[
{
"count":5,
"value":"Capacity:Extra Small",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":11,
"value":"Capacity:Large",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":13,
"value":"Capacity:Medium",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":19,
"value":"Capacity:Small",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":8,
"value":"Coffee at the press of a button?:Yes",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":13,
"value":"Extraction Quality:Amazing",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":5,
"value":"Extraction Quality:Exceptional",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":24,
"value":"Extraction Quality:Good",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":6,
"value":"Extraction Quality:Very Good",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":16,
"value":"Milk Frother:Automatic",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":10,
"value":"Milk Frother:None",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":22,
"value":"Milk Frother:Steam Wand",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":10,
"value":"Noise:Buzzing",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":10,
"value":"Noise:Loud",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":23,
"value":"Noise:Quiet",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":5,
"value":"Noise:Silent",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":3,
"value":"Size:Extra Small",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":6,
"value":"Size:Large",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":31,
"value":"Size:Medium",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":8,
"value":"Size:Small",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":2,
"value":"Speed:Instant",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":28,
"value":"Speed:Quick Heat",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":5,
"value":"Speed:Slow",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":13,
"value":"Speed:Standard",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":7,
"value":"Style:Designer",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":8,
"value":"Style:Minimalist",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":20,
"value":"Style:Modern",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":13,
"value":"Style:Professional",
"from":null,
"to":null,
"__typename":"FacetModel"
}
],
"__typename":"KeyValuePairOfStringAndListOfFacetModel"
}
]
在这个组件中,当其中一个项目被点击时,它会执行一个返回一组新构面的搜索。以下是新数组的示例:
[
{
"key":"Criteria/Attribute",
"value":[
{
"count":5,
"value":"Capacity:Extra Small",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":5,
"value":"Extraction Quality:Good",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":5,
"value":"Milk Frother:None",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":5,
"value":"Noise:Silent",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":5,
"value":"Speed:Slow",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":5,
"value":"Style:Minimalist",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":3,
"value":"Size:Extra Small",
"from":null,
"to":null,
"__typename":"FacetModel"
},
{
"count":2,
"value":"Size:Medium",
"from":null,
"to":null,
"__typename":"FacetModel"
}
],
"__typename":"KeyValuePairOfStringAndListOfFacetModel"
}
]
这一切都由父组件提供。初始数组是在页面加载时生成的,当点击上面的过滤器时,它会调用一个方法来更新 Chooser 组件使用的数组。
<chooser
:categoryName="category.name"
:facets="result.search.facets"
:loading="loading"
@onFilter="search($event)"
>
</chooser>
问题是,即使我可以在父组件中执行{{ result.search.facets }} 并看到数组更改,Chooser 仍然完全相同。
为了让 Chooser 在数组更改时更新,我必须做些什么吗?
【问题讨论】:
-
你是在改变
result.search.facets数组还是完全替换它? -
criteria应该是computed,所以每次fasets属性更改时都会重建(通过执行getFacets函数)。 -
完全替换它