Reputation: 95
I am new to vuejs and I am making an app which should filters all the data from database and filter parameters should be passed in URL, so that it remain in the page even after page refresh.
Firstly, I want to push search params in URL
My current Url localhost:8080/product
I want my Url to be like below when user click checkboxes
localhost:8080/product?color=red&color=green&size=small
(When user checks red, green and small options)
So far, I have done this and I am stuck how to get dynamic color in $this.router.push()
, and append it to URL
<template>
<div class="products">
<h1>Filter By Color</h1>
<input @click="filterData" v-model="colortype" type="checkbox">Red color
<input @click="filterData" v-model="colortype" type="checkbox">Green color
<input @click="filterData" v-model="colortype" type="checkbox">Yellow color
<h1>Filter By Size</h1>
<input @click="filterData" v-model="size" type="radio">Big
<input @click="filterData" v-model="size" type="radio">Small
</div>
</template>
<script>
export default {
data() {
return {
colortype:''
}
},
methods:{
filterData() {
this.$router.push({ path: "product", query: { color: "red" } });
}
}
}
</script>
Any suggestions, once I push params to URL, I want to do api request to endpoint in filterData
method.
Upvotes: 1
Views: 2393
Reputation: 211
There is a pattern you can use for this:
The following snippets demonstrate a dropdown where you can pick one value to filter on.
<template>
<div>
Color:
<select v-model="filter.color">
<option v-for="item in colors" :key="item.value" :value="item.value">
{{ item.name }}
</option>
</select>
</div>
</template>
export default {
name: "MyComponent",
data: () => ({
filter: {
color: null,
},
colors: [{name: 'Black', value: 'black'}, {name: 'Red', value: 'red'}],
}),
watch: {
'filter': {
deep: true,
handler(filter) {
this.$router.replace({
...this.$route,
query: {
color: filter.color.value,
// TODO: Convert `filter` to params
},
});
this.search(filter);
},
},
},
};
For the case where there a field accepts multiple values (e.g. using checkboxes) I'd suggest to put all values on the filter object and have each option mark its checked-ness with a flag. The following snippets demonstrate that technique:
<template>
<div>
Sizes:
<label v-for="size in sizes" :key="size.value">
<input type="checkbox" v-model="size.active">
{{ size.name }}
</label>
</div>
</template>
export default {
data: () => ({
filter: {
sizes: [{name: 'Small', value: 'small', active: false}],
},
}),
watch: {
filter: {
deep: true,
handler() {
this.$router.replace({
...this.$route,
params: {
sizes: this.filter.sizes
.filter(size => size.active)
.map(size => size.value)
.join('+'),
},
});
},
},
},
}
Upvotes: 1