I'm trying to use watch property of vuejs to perform action when my $route.params.slug change, but it's seems doen't work...
My $route.params.slug actualy change when i click to my router-link but the watcher's not triggered...
There is my app.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Clients from './components/ClientsComponent'
import Slider from './components/SliderComponent'
import store from './store/store'
require('./bootstrap');
Vue.use(VueRouter)
const routes = [
{path: '/references/clients', component: Slider, name: 'client'},
{path: '/references/clients/:slug-:id', component: Slider, name: 'client.show'}
]
const router = new VueRouter({
mode: 'history',
routes
})
const app = new Vue({
el: '#app',
store: store,
router,
components: {
Clients,
Slider
}
});
My store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
strict: true,
state: {
clients: {},
clientsPacks: [],
slides: {}
},
getters: {
clients: function (state) {
return state.clients
},
clientsPacks: function (state) {
return state.clientsPacks
},
slides: function (state) {
return state.slides
}
},
mutations: {
addClient: function (state, {clients}) {
let obj = {}
let array = []
let arraysPack = []
let arraysPacks = []
clients.forEach(function (client) {
array.push(client)
obj[client.id] = client
})
for (let i = 0; i < Math.ceil(array.length/9); i++) {
arraysPack = []
for (let y = i*9; y < 9 + i*9; y++) {
if (y < array.length) {
arraysPack.push(array[y])
}
}
arraysPacks.push(arraysPack)
}
state.clients = obj
state.clientsPacks = arraysPacks
},
addSlide: function (state, {slides}) {
let obj = {}
slides.forEach(function (slide) {
obj[slide.pos] = slide
})
state.slides = obj
}
},
actions: {
loadClients: async function (context) {
axios.get('/api/clients')
.then((response) => {
context.commit('addClient', {
clients: response.data.clients
})
})
.catch((error) => {
console.log(error);
throw new Error(error)
});
},
loadSlides: async function (context, slug) {
axios.get('/api/slides/' + slug)
.then((response) => {
context.commit('addSlide', {
slides: response.data.slides
})
})
.catch((error) => {
console.log(error);
throw new Error(error)
});
}
}
})
And my Components
ClientsComponent.vue
<template>
<section id="clients">
<article class="col-md-6 mosaic">
<div v-if="clientsPacks.length > 1" id="Carousel" class="carousel vertical slide" data-ride="carousel" data-interval="false">
<!-- Wrapper for slides -->
<div class="carousel-inner">
<div v-for="(clientsPack, index) in clientsPacks" class="item" :class="{ 'active': index === 0 }">
<div v-for="client in clientsPack" class="col-sm-4 mosaic-item client">
<router-link
:to="{
name: 'client.show',
params: {
slug: slugify(client.title),
id: client.id
}
}">
<div class="embed-responsive embed-responsive-16by9">
<div class="slide-image embed-responsive-item" :style="{ backgroundImage: 'url(\'/storage/' + client.logo_URL + '\')' }"></div>
</div>
</router-link>
</div>
</div>
</div>
<!-- Left and right controls -->
<a class="left carousel-control" href="#Carousel" data-slide="prev">
<span class="fa fa-chevron-left"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#Carousel" data-slide="next">
<span class="fa fa-chevron-right"></span>
<span class="sr-only">Next</span>
</a>
</div>
<div v-else>
<div v-for="client in clients" class="col-sm-4 mosaic-item client">
<router-link
:to="{
name: 'client.show',
params: {
slug: slugify(client.title),
id: client.id
}
}">
<div class="embed-responsive embed-responsive-16by9">
<div class="slide-image embed-responsive-item" :style="{ backgroundImage: 'url(\'/storage/' + client.logo_URL + '\')' }"></div>
</div>
</router-link>
</div>
</div>
</article>
<article class="col-md-6">
<router-view></router-view>
</article>
</section>
</template>
<script>
import {mapGetters} from 'vuex'
export default {
props: {
client: Number
},
computed: {
...mapGetters(['clients']),
...mapGetters(['clientsPacks'])
},
mounted () {
this.$store.dispatch('loadClients')
},
methods: {
slugify: function (value) {
if (!value) return ''
var slug = "";
// Change to lower case
var valueLower = value.toLowerCase();
// Letter "e"
slug = valueLower.replace(/e|é|è|ẽ|ẻ|ẹ|ê|ế|ề|ễ|ể|ệ/gi, 'e');
// Letter "a"
slug = slug.replace(/a|á|à|ã|ả|ạ|ă|ắ|ằ|ẵ|ẳ|ặ|â|ấ|ầ|ẫ|ẩ|ậ/gi, 'a');
// Letter "o"
slug = slug.replace(/o|ó|ò|õ|ỏ|ọ|ô|ố|ồ|ỗ|ổ|ộ|ơ|ớ|ờ|ỡ|ở|ợ/gi, 'o');
// Letter "u"
slug = slug.replace(/u|ú|ù|ũ|ủ|ụ|ư|ứ|ừ|ữ|ử|ự/gi, 'u');
// Letter "d"
slug = slug.replace(/đ/gi, 'd');
// Trim the last whitespace
slug = slug.replace(/\s*$/g, '');
// Change whitespace to "-"
slug = slug.replace(/\s+/g, '_');
return slug;
}
}
}
</script>
SliderComponent.vue
<template>
<div id="MainCarousel" class="carousel move-carousel slide" data-ride="carousel">
<!-- Indicators -->
<ol class="carousel-indicators">
<li v-for="slide in slides" data-target="#MainCarousel" data-slide-to="{ slide.pos - 1 }" :class="{ 'active': slide.pos == 1 }"></li>
</ol>
<!-- Wrapper for slides -->
<div class="carousel-inner">
<div v-for="slide in slides" class="item" :class="{ 'active': slide.pos == 1 }">
<div class="embed-responsive embed-responsive-16by9">
<div class="slide-image embed-responsive-item" :style="{ backgroundImage: 'url(\'/storage/' + slide.image_URL + '\')' }"></div>
</div>
<div class="carousel-caption">
<div class="col-xs-10 vcenter">
<h3>{{ slide.title }}</h3>
<p>{{ slide.caption }}</p>
</div><!--
--><div class="col-xs-2 logo vcenter">
<img v-if="slide.client_logo_URL" :src="'/storage/' + slide.client_logo_URL" width="100%">
</div>
</div>
</div>
</div>
<!-- Left and right controls -->
<a class="left carousel-control" href="#MainCarousel" data-slide="prev">
<span class="fa fa-chevron-left"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#MainCarousel" data-slide="next">
<span class="fa fa-chevron-right"></span>
<span class="sr-only">Next</span>
</a>
</div>
</template>
<script>
import {mapGetters} from 'vuex'
export default {
props: {
slide: Number
},
computed: {
...mapGetters(['slides'])
},
mounted () {
this.loadSlides ()
},
watch: {
'this.$route.params.slug': function () {
this.loadSlides ()
}
},
methods: {
loadSlides () {
console.log(this.$route.params.slug)
this.$store.dispatch('loadSlides', this.$route.params.slug)
}
}
}
</script>
I google it since 3 hours and i'm going crazy with this so...
Thank's for help.
You should watch $route.params.slug
instead of this.$route.params.slug
watch: {
'$route.params.slug': function () {
this.loadSlides ()
}
},
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With