vuex-router-sync 有啥用?
Posted
技术标签:
【中文标题】vuex-router-sync 有啥用?【英文标题】:what is vuex-router-sync for?vuex-router-sync 有什么用? 【发布时间】:2017-10-25 13:19:39 【问题描述】:据我所知vuex-router-sync
仅用于将route
与vuex store
同步,开发人员可以访问route
,如下所示:
store.state.route.path
store.state.route.params
不过,我也可以通过this.$route
处理route
,这样更简洁。
什么时候需要使用store中的路由,什么场景需要vuex-router-sync?
【问题讨论】:
【参考方案1】:这是我的两分钱。如果您在项目中无法弄清楚它的用例,则不需要导入vuex-router-sync
,但是当您尝试在vuex
的方法中使用route
对象时可能需要它(this.$route
赢了'在 vuex 的领域不能很好地工作)。
我想在这里举个例子。
假设您想在一个组件中显示一条消息。您希望在几乎每个页面中都显示类似Have a nice day, Jack
的消息,除了在用户浏览首页时应该显示Welcome back, 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
如您所见,组件与vuex
和vue-router
的逻辑很好地解耦。
当您不关心当前路由与 vuex 的 getter 返回的值之间的关系时,这种模式有时会非常有效。
【讨论】:
named views 最适合我!文档链接:router.vuejs.org/guide/essentials/named-views.html【参考方案2】:我在学习 Vue 的时候看到了这个帖子。补充了我对这个问题的一些理解。
Vuex 为 Vue 应用程序定义了一种状态管理模式。我们没有定义组件 props 并在所有地方通过 props 传递共享状态,而是使用集中存储来组织多个组件共享的状态。对状态突变的限制使状态转换更清晰,更容易推理。
理想情况下,如果提供的商店状态相同,我们应该获得/构建一致(或相同)的视图。但是,由多个组件共享的路由器打破了这一点。如果我们需要推理为什么页面会按原样呈现,如果我们从this.$router
属性派生视图,我们需要检查存储状态以及路由器状态。
vuex-router-sync
是将路由器状态同步到集中状态存储的助手。现在所有视图都可以从状态存储中构建,我们不需要检查this.$router
。
注意route
状态是不可变的,我们应该通过$router.push
或$router.go
调用来“改变”它的状态。将 store 上的一些操作定义为:
// import your router definition
import router from './router'
export default new Vuex.Store(
//...
actions:
//...
// actions to update route asynchronously
routerPush (_, arg)
router.push(arg)
,
routerGo (_, arg)
router.go(arg)
)
这将 route
更新包装在 store 操作中,我们可以完全摆脱组件中的 this.$router
依赖项。
【讨论】:
以上是关于vuex-router-sync 有啥用?的主要内容,如果未能解决你的问题,请参考以下文章