2017-05-25 66 views
8

正如我知道,vuex-router-sync只是同步routestore和开发人员可以阅读route为波纹管vuex-router-sync的用途是什么?

store.state.route.path 
store.state.route.params 

不过,我也可以通过this.$route哪个更简洁的处理route

我需要哪个场景?

回答

8

这是我的两美分。如果您无法在您的项目中找出其用例,则无需导入vuex-router-sync,但当您尝试在vuex的方法中尝试使用route对象时(this.$route在vuex的领域中不适用) 。

我想在这里举个例子。
假设您想在一个组件中显示消息。除了在用户浏览首页时应显示Welcome back, Jack的情况之外,几乎每个页面中都要显示Have a nice day, Jack之类的消息。

您可以在vuex-router-sync的帮助下轻松实现。

const Top = { 
 
    template: '<div>{{message}}</div>', 
 
    computed: { 
 
    message() { 
 
     return this.$store.getters.getMessage; 
 
    } 
 
    }, 
 
}; 
 
const Bar = { 
 
    template: '<div>{{message}}</div>', 
 
    computed: { 
 
    message() { 
 
     return this.$store.getters.getMessage; 
 
    } 
 
    } 
 
}; 
 

 
const routes = [{ 
 
    path: '/top', 
 
    component: Top, 
 
    name: 'top' 
 
    }, 
 
    { 
 
    path: '/bar', 
 
    component: Bar, 
 
    name: 'bar' 
 
    }, 
 
]; 
 

 
const router = new VueRouter({ 
 
    routes 
 
}); 
 

 
const store = new Vuex.Store({ 
 
    state: { 
 
    username: 'Jack', 
 
    phrases: ['Welcome back', 'Have a nice day'], 
 
    }, 
 
    getters: { 
 
    getMessage(state) { 
 
     return state.route.name === 'top' ? 
 
     `${state.phrases[0]}, ${state.username}` : 
 
     `${state.phrases[1]}, ${state.username}`; 
 
    }, 
 
    }, 
 
}); 
 

 
// sync store and router by using `vuex-router-sync` 
 
sync(store, router); 
 

 
const app = new Vue({ 
 
    router, 
 
    store, 
 
}).$mount('#app'); 
 

 

 

 

 

 

 

 

 

 

 

 

 
// vuex-router-sync source code pasted here because no proper cdn service found 
 
function sync(store, router, options) { 
 
    var moduleName = (options || {}).moduleName || 'route' 
 

 
    store.registerModule(moduleName, { 
 
    namespaced: true, 
 
    state: cloneRoute(router.currentRoute), 
 
    mutations: { 
 
     'ROUTE_CHANGED': function(state, transition) { 
 
     store.state[moduleName] = cloneRoute(transition.to, transition.from) 
 
     } 
 
    } 
 
    }) 
 

 
    var isTimeTraveling = false 
 
    var currentPath 
 

 
    // sync router on store change 
 
    store.watch(
 
    function(state) { 
 
     return state[moduleName] 
 
    }, 
 
    function(route) { 
 
     if (route.fullPath === currentPath) { 
 
     return 
 
     } 
 
     isTimeTraveling = true 
 
     var methodToUse = currentPath == null ? 
 
     'replace' : 
 
     'push' 
 
     currentPath = route.fullPath 
 
     router[methodToUse](route) 
 
    }, { 
 
     sync: true 
 
    } 
 
) 
 

 
    // sync store on router navigation 
 
    router.afterEach(function(to, from) { 
 
    if (isTimeTraveling) { 
 
     isTimeTraveling = false 
 
     return 
 
    } 
 
    currentPath = to.fullPath 
 
    store.commit(moduleName + '/ROUTE_CHANGED', { 
 
     to: to, 
 
     from: from 
 
    }) 
 
    }) 
 
} 
 

 
function cloneRoute(to, from) { 
 
    var clone = { 
 
    name: to.name, 
 
    path: to.path, 
 
    hash: to.hash, 
 
    query: to.query, 
 
    params: to.params, 
 
    fullPath: to.fullPath, 
 
    meta: to.meta 
 
    } 
 
    if (from) { 
 
    clone.from = cloneRoute(from) 
 
    } 
 
    return Object.freeze(clone) 
 
}
.router-link-active { 
 
    color: red; 
 
}
<script src="https://unpkg.com/vue/dist/vue.js"></script> 
 
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> 
 
<script src="https://unpkg.com/vuex/dist/vuex.js"></script> 
 

 
<div id="app"> 
 
    <p> 
 
    <router-link to="/top">Go to Top</router-link> 
 
    <router-link to="/bar">Go to Bar</router-link> 
 
    </p> 
 
    <router-view></router-view> 
 
</div>

fiddle here

正如你所看到的,组件以及从vuexvue-router的逻辑分离。
这种模式有时对于您不关心当前路线与从vuex的getter返回的值之间的关系的情况有效地起作用。