我正在创建一个nuxt电子商务应用程序。我遇到一个类别中有10,000多个项目的情况,并且我想为产品创建相关的过滤器。
我的问题是我如何附加网址(添加和删除查询参数),以便我可以过滤产品。
我已经通过向{1>添加一个change
事件来尝试这样的事情。
<ul>
<li>
<b-form-checkbox @change="filterProduct">
<label class="ui__label_checkbox">Apple</label>
</b-form-checkbox>
</li>
<li >
<b-form-checkbox @change="filterProduct">
<label class="ui__label_checkbox">Mango</label>
</b-form-checkbox>
</li>
</ul>
methods:{
filterProduct() {
this.$router.push({ query: Object.assign({}, this.$route.query, { random: "query" }) });
},
}
此方法做仅将URL附加一次,但会删除我不想要的复选框的选中状态
我希望每次单击复选框时都与下面类似,它必须同时保留复选框的状态并附加到url
www.foobar.com/?first=1&second=12&third=5
答案 0 :(得分:2)
这是您应该做的。首先,您应将所有过滤器的状态都设置为data()
data() {
return {
filter: {
first: this.$route.params.first || null,
second: this.$route.params.second || null,
third: this.$route.params.third || null
}
}
}
然后,您设置了一个观察者,当任何过滤器发生更改时将触发该观察者,显然,您需要将<template>
中的输入v建模到data()
中的字段
watch() {
filter: {
handler(newFilters) {
const q = complexToQueryString({
...this.filter,
})
const path = `${this.$route.path}?${q}`
this.$router.push(path)
}
}
}
complexToQueryString函数是我的事情,它从查询中删除空值,并且也适用于数组过滤器。我这样做是因为我的API将null读取为String'null'。
const complexToQueryString = (object, parentNode = null) => {
const query = Object.entries(object).map((item) => {
const key = parentNode ? `${parentNode}[${item[0]}]` : item[0]
const value = item[1]
if (Array.isArray(value)) {
return arrayToQueryString(value, key)
} else if (value instanceof Object) {
return complexToQueryString(value, key)
} else if (item[1] !== undefined) {
return [
Array.isArray(item[0]) ? `${key}[]` : key,
encodeURIComponent(item[1]),
].join('=')
}
return ''
})
.filter(empty => empty)
.join('&')
return query
}
现在它应该可以工作,如果您更改过滤器值,那么data.filter.first会更改该值,从而触发观察程序,并更新URL。
关于此方法的最好的事情是,现在您可以复制并粘贴URL,并且过滤器完全相同,并返回相同的结果。
答案 1 :(得分:0)
您的方法几乎是正确的,只是在页面请求上是路由器级的,您应该将所有查询参数附加到路由参数上。
然后将这些参数分配给您的过滤器页面中的数据,并对它们进行突变,也像您现在所做的那样更新查询。这样,您将更新查询,并且复选框不会丢失状态,因为它们将取决于数据而不是参数。
routes: [{
path: '/path',
component: Component,
props: (route) => ({
filter1: route.query.filter1,
filter2: route.query.filter2,
filter3: route.query.filter3
})
}]