0
点赞
收藏
分享

微信扫一扫

vuex-router-sync 源码解析

鱼板番茄 2023-03-08 阅读 104


vuex-router-sync:路由状态管理,保持 vue-router 和 vuex 存储同步。

import { sync } from 'vuex-router-sync'
import router from '@/router'
import store from '@/store'

sync(store,router)

new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})

vuex-router-sync 源码解析_vue-router

第1步:vuex模块动态注册

const moduleName = (options || {}).moduleName || 'route' 
store.registerModule(moduleName, {
namespaced: true,
state: cloneRoute(router.currentRoute), // route 全部属性
mutations: {
// 改变 state 值
'ROUTE_CHANGED'(state, transition) {
store.state[moduleName] = cloneRoute(transition.to, transition.from)
}
}
})

第2步:​​store.watch => vueVm.$watch​

​watch(fn: Function, callback: Function, options?: Object): Function​

响应式地侦听 ​​fn​​ 的返回值,当值改变时调用回调函数。

  • ​fn​​ 接收 store 的 state 作为第一个参数,其 getter 作为第二个参数。
  • ​callback(newVal, oldVal)​​,回调函数
  • 最后接收一个可选的对象参数表示 Vue 的 vm.$watch 方法的参数

const storeUnwatch = store.watch(
// 监听 state[moduleName]
state => state[moduleName],
route => {
const {
fullPath
} = route
if (fullPath === currentPath) {
return
}
if (currentPath != null) {
isTimeTraveling = true
// 路由跳转
router.push(route)
}
currentPath = fullPath
}, {
sync: true
}
)

第3步:vue-router 全局后置导航钩子,钩子不会接受 ​​next​​ 函数也不会改变导航本身

// 监听路由变化
router.afterEach((to, from) => {
if (isTimeTraveling) {
isTimeTraveling = false
return
}
currentPath = to.fullPath
// 触发 mutation
store.commit(moduleName + '/ROUTE_CHANGED', {
to,
from
})
})

为了避免循环调用,isTimeTraveling 为true时,代表是当前组件触发的路由跳转,​​router.afterEach​​​ 监听到不做任何处理。
这里需要注意的点是,我们通过 @/router​@store​ 来获取相关实例!当然 ​vueVM.$options​ 也可以获取!


举报

相关推荐

0 条评论