Есть динамический роут, который выводит отфильтрованный список товаров, фильтрация происходит в getter во vuex, все бы ничего, но если перезагрузить страницу находясь в этом компоненте список не отобразиться тк параметры для фильтрация из родительского компонента не передались. Пробовал использовать хуки, и keep-alive, не помогло. Подскажите как решить данную проблему или посоветуйте бест практисы в таких случаях.
Используя входные параметры во Vue router, вы можете создать фильтр данных по этим параметрам.
Для этого:
Создаете роуты. Для передачи входных параметров, можете использовать функцию, объект, булевы значения. Обратите внимание, когда используете булево значение как true
- route.params
будут устанавливаться входными параметрами компонента(это касается только route.params
). В примере ниже используется функция, которая позволяет приводить параметры к другим типам, комбинировать статические значения с значениями из маршрута(позволяет использовать как route.params
так и route.query.*
):
routes: [
{
path: "/",
component: vcatalog,
},
{
path: "/products/",
component: vcatalog,
},
{
path: "/products/:brand",
component: vcatalog,
props: (route) => ({ // функции генерации входных параметров
type: route.query.type,
brand: route.params.brand,
}),
},
],
Создаете компонент, который используется в роутах, как:
const vcatalog = Vue.component("vcatalog", {
store,
props: ["brand", "type"], // инициируем необходимые параметры
computed: {
...mapGetters(["GET_PRODUCTS", "SORTED_PRODUCT"]),
},
template: `<div>
<p>Входные параметры (props)</p>
<pre>{{ $props }}</pre>
<hr>
<template v-if="brand && type"><ul>
<li v-for="product in SORTED_PRODUCT(brand,type)"> {{ product.text }} ({{ product.type }}/ {{ product.brand }}) </li>
</ul>
</template>
<template v-else>
<ul>
<li v-for="product in GET_PRODUCTS"> {{ product.text }} ({{ product.type }}/ {{ product.brand }}) </li>
</ul>
</template>
</pre>
</div>`,
});
И на выходе вы получите маршруты, которые будут содержать входные параметры, которые будут внедрены в ваш компонент и доступными для использования их в вашей дальнейшей логике (фильтрация и прочее)
Привожу рабочий пример
const {
mapGetters
} = Vuex;
const store = new Vuex.Store({
state: {
products: [{
id: 1,
text: "Продукт 1",
type: "type1",
brand: "brand1"
},
{
id: 2,
text: "Продукт 2",
type: "type2",
brand: "brand2"
},
{
id: 3,
text: "Продукт 3",
type: "type1",
brand: "brand2"
},
{
id: 4,
text: "Продукт 4",
type: "type1",
brand: "brand1"
},
{
id: 5,
text: "Продукт 5",
type: "type2",
brand: "brand2"
},
],
},
getters: {
GET_PRODUCTS: (state) => (brand) => {
return brand ? state.products.filter((p) => p.brand === brand) : state.products;
},
SORTED_PRODUCT: (state) => (brand, type) => {
return state.products.filter(
(p) => p.brand === brand && p.type === type
);
},
},
});
const vcatalog = Vue.component("vcatalog", {
store,
props: ["brand", "type"],
computed: {
...mapGetters(["GET_PRODUCTS", "SORTED_PRODUCT"]),
},
template: `<div>
<p>Входные параметры (props)</p>
<pre>{{ $props }}</pre>
<hr>
<template v-if="brand && type"><ul>
<li v-for="product in SORTED_PRODUCT(brand,type)"> {{ product.text }} ({{ product.type }}/ {{ product.brand }}) </li>
</ul>
</template>
<template v-else>
<ul>
<li v-for="product in GET_PRODUCTS(brand)"> {{ product.text }} ({{ product.type }}/ {{ product.brand }}) </li>
</ul>
</template>
</pre>
</div>`,
});
const router = new VueRouter({
routes: [{
path: "/",
redirect: '/products'
},
{
path: "/products/",
component: vcatalog,
name: 'catalog'
},
{
path: "/products/:brand",
name: 'brand',
component: vcatalog,
props: (route) => ({
type: route.query.type,
brand: route.params.brand,
}),
},
],
});
new Vue({
el: "#app",
router,
watch: {
"$route.fullPath": {
handler: function(path) {
this.setNewPath(path);
},
},
},
created() {
this.setNewPath();
},
methods: {
goPath() {
this.$router.push(this.path);
},
setNewPath(path) {
this.path = path || this.$route.fullPath;
},
},
});
.router-link-active { color: green }
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<script src="https://unpkg.com/vuex@3.3.0/dist/vuex.js"></script>
<div id="app">
<router-view></router-view>
<label for="input">Текущий URL</label>
<hr>
<input id="input" v-if="path" type="text" name="path" v-model="path" style="width: 100%; padding: 10px" @keyup.enter="goPath" />
<p>Тестовые URL</p>
<ul>
<li>
<router-link exact :to="{name: 'catalog'}">/products</router-link>
</li>
<li>
<router-link exact to="/products/brand2?type=type2">/products/brand2?type=type2</router-link>
</li>
<li>
<router-link exact to="/products/brand1?type=type1">/products/brand1?type=type1</router-link>
</li>
<li>
<router-link exact :to="{path: '/products/brand1' }">/products/brand1</router-link>
</li>
<li>
<router-link exact :to="{name: 'brand', params: { brand: 'brand2'} }">/products/brand2</router-link>
</li>
<li>
<router-link exact :to="{name: 'brand', params: { brand: 'brand2'}, query: { type: 'type1' } }">/products/brand2?type=type1</router-link>
</li>
</ul>
</div>
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Какие существуют виды рекламных бордов и как выбрать подходящий?
Если пишем новое имя, программа просит ввести номер телефона и запоминает егоЕсли новый номер телефона — просит ввести имя и также запоминает
Подскажите, как передать объект в форме springЯ использую Thymeleaf