观看$ route.params.slug没有触发vue.js

时间:2018-09-25 07:28:25

标签: javascript vue.js vuejs2 vue-router watch

我试图在$ route.params.slug更改时使用vuejs的watch属性执行操作,但似乎不起作用...

当我单击到路由器链接时,我的$ route.params.slug实际上发生了变化,但观察者未触发...

有我的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
    }
});

我的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)
                });
        }
    }
})

还有我的组件

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>

我从3个小时以来一直在Google上搜索,因此我为此而发疯...

感谢您的帮助。

1 个答案:

答案 0 :(得分:4)

您应该观看$route.params.slug而不是this.$route.params.slug

  watch: {
            '$route.params.slug': function () {
                this.loadSlides ()
            }
  },