前端入门之(vuex-router-sync解析)

发布时间:2018-11-14 13:31,

浏览次数:513

, 标签:

vuex

router

sync

前言:vue全家桶的内容我们已经研究过了vuex、vue-router,有兴趣的童鞋可以去看看我之前的两个系列的文章vuex源码解析一

、vue-router全解析一

,之前结合项目分析vuex的时候,当我们需要在vuex的action中处理路由跳转的时候,没认识vuex-router-sync的时候,我一般都是直接拿到router对象,然后稍微封装了一下进行跳转的,哈哈~~

在看vue的github官网的时候不小心看到了vuex-router-sync,哈哈!!

才知道原来官方已经有一个工具把store跟router连接起来了,翻了一下vuex-router-sync的源码才知道原来还可以这么操作?于是打算把自己所理解的内容记录下来,欢迎指正,大牛勿喷!!!

我们直接执行:

npm install vuex-router-sync --save

然后配置就很简单了:

import Vue from 'vue' import App from './App' import router from './router'

import store from './store' import {sync} from 'vuex-router-sync' /*

eslint-disable no-new */ new Vue({ el: '#app', router, store, ddd: {name:

'yasin'}, render(h) { return h(App) } })

只需要通过sync方法把store跟router连接起来就可以了

然后我们在vue组件的mounted方法中打印一下route内容:

mounted(){ console.log(this.$store.state.route) }

我们可以看到,在store的route对象其实就是我们router中的currentRoute对象(当前路由).

好啦~

到这我们小伙伴可能要疑问啦,我直接用this.$router.route也可以拿到currentRoute对象啊,为啥还这么复杂呢?这样做又有啥好处呢?不急不急,我们直接看看它的源码来研究下它的功能哈~~

我们找到vuex-router-sync的源码:

exports.sync = function (store, router, options) { var moduleName = (options

|| {}).moduleName || 'route' store.registerModule(moduleName, { namespaced:

true, state: cloneRoute(router.currentRoute), mutations: { 'ROUTE_CHANGED':

function ROUTE_CHANGED (state, transition) { store.state[moduleName] =

cloneRoute(transition.to, transition.from) } } }) var isTimeTraveling = false

var currentPath // sync router on store change var storeUnwatch = store.watch(

function (state) { return state[moduleName]; }, function (route) { var fullPath

= route.fullPath; if (fullPath === currentPath) { return } if (currentPath !=

null) { isTimeTraveling = true router.push(route) } currentPath = fullPath }, {

sync: true } ) // sync store on router navigation var afterEachUnHook =

router.afterEach(function (to, from) { if (isTimeTraveling) { isTimeTraveling =

false return } currentPath = to.fullPath store.commit(moduleName +

'/ROUTE_CHANGED', { to: to, from: from }) }) return function unsync () { // On

unsync, remove router hook if (afterEachUnHook != null) { afterEachUnHook() }

// On unsync, remove store watch if (storeUnwatch != null) { storeUnwatch() }

// On unsync, unregister Module with store store.unregisterModule(moduleName) }

} 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) }

好吧,简单的不能再简单了,就70多行代码,这可是在github上好几k的star的库啊~~~ 小伙伴是不是跟我一样惊讶呢?

小伙伴莫及哈,代码虽少,但其中的思路跟用法还是值得我们学习的,这也是我为啥写这篇文章的原因了~ 废话不多说了,我们开始带着源码往下走.

首先是在我们的store中注册了一个module,名字默认为“route”:

store.registerModule(moduleName, { namespaced: true, state:

cloneRoute(router.currentRoute), mutations: { 'ROUTE_CHANGED': function

ROUTE_CHANGED (state, transition) { store.state[moduleName] =

cloneRoute(transition.to, transition.from) } } })

module中提供了一个叫“ROUTE_CHANGED”的mutation处理方法,然后还把router对象中的currentRoute保存在了state中,这也是我们为什么能够通过this.$store.state.route拿到currentRoute的原因.

然后就是监听store中的route对象的变化了,当route发生变化并且当前路由名字不等于需要跳转到路由的时候,直接通过router的push方法进行跳转页面:

var storeUnwatch = store.watch( function (state) { return state[moduleName];

}, function (route) { var fullPath = route.fullPath; if (fullPath ===

currentPath) { return } if (currentPath != null) { isTimeTraveling = true

router.push(route) } currentPath = fullPath }, { sync: true } )

store的watch方法我简单说一下,watch跟我们vue中的watch是一个概念,也就是检测某个属性的变化,然后回调.

最后通过router的全局后置钩子函数监听当前路由对象,修改store中的当前state(当前路由对象):

// sync store on router navigation var afterEachUnHook =

router.afterEach(function (to, from) { if (isTimeTraveling) { isTimeTraveling =

false return } currentPath = to.fullPath store.commit(moduleName +

'/ROUTE_CHANGED', { to: to, from: from }) })

好啦,整个库的源码算是分析完毕了,小伙伴是不是还是很疑问呢? 这东西怎么用呢? 我们接下来结合一个demo来用用它~

一般来说项目为了让页面跟数据逻辑分离出来,一般一些逻辑处理都在vuex的action中进行了,我就简单结合之前的博客中的demo操作了~

我们运行项目看到有一个a页面:

我是a页面

export default { name: 'pageA', mounted(){ console.log(this.$store.state.route)

} }

white; font-size: 24px; height: 100%; }

然后我们项目可能有这么一个需求:“当点击a页面的某个按钮的时候,我们会调后台接口,然后再跳转某个具体的页面~”

我们在a页面放一个“登录”按钮,然后点击去登录,登录成功跳转到登录成功页面:

page-a.vue:

我是a页面

@click="onClick">登录

'pageA', mounted() { console.log(this.$store.state.route) }, methods: {

onClick() { this.$store.dispatch('login') } } }

#page-a-container { background-color: red; color: white; font-size: 24px;

height: 100%; }

然后store中的action:

login({state, commit}) { setTimeout(() => { alert('登录成功')

commit('route/ROUTE_CHANGED',{to: {path: '/b'}}) }, 1000) }

我们直接模拟一下登录,然后跳转到b页面

好啦!! 我们vuex-router-sync就分析到这啦~~

欢迎入群,欢迎交流,qq群链接:

vuex 源码分析_前端入门之(vuex-router-sync解析)相关推荐

  1. vuex 源码分析_深入Vuex原理(上)

    原标题:深入Vuex原理(上) 孔维国,2016年加入去哪儿网技术团队.目前在大住宿事业部/增值业务研发中心,参与开发了TMC.CRM.QTA.Auth等项目,负责node框架nomi的设计以及开发. ...

  2. 从vuex源码分析module与namespaced

    使用vue已经有半年有余, 在各种正式非正式项目中用过, 开始专注于业务比较多, 用到现在也遇见不少因为理解不深导致的问题. 有问题就有找原因的勇气, 所以带着问题搞一波. 带着问题看源码 所以来整理 ...

  3. 逐行粒度的vuex源码分析

    vuex源码分析 了解vuex 什么是vuex vuex是一个为vue进行统一状态管理的状态管理器,主要分为state, getters, mutations, actions几个部分, vue组件基 ...

  4. SpringMVC源码分析_框架原理图

                                                                                 SpringMVC源码分析_框架原理图     ...

  5. vuex 源码分析_Vuex 2.0 源码分析(下)

    大家好,我叫黄轶,来自滴滴公共前端团队,最近在幕课网上线了一门 Vue.js 的实战课程--<Vue.js高仿饿了么外卖App 2016最火前端框架>,同时,我们团队最近写了一本书 --& ...

  6. vuex 源码分析_Vuex框架原理与源码分析

    Vuex是一个专为Vue服务,用于管理页面数据状态.提供统一数据操作的生态系统.它集中于MVC模式中的Model层,规定所有的数据操作必须通过 action - mutation - state ch ...

  7. vuex 源码分析_vue源码解析之vuex原理

    常用接口 dispatch 操作行为触发方法,是唯一能执行action的方法. actions 操作行为处理模块.负责处理Vue Components接收到的所有交互行为.包含同步/异步操作,支持多个 ...

  8. Dubbo源码分析:小白入门篇

    关注公众号"java后端技术全栈" 回复"000"获取优质面试资料 大家好,我是老田 答应了小伙伴的Dubbo源码分析系列,今天终于来了,希望不是很晚. 主要也 ...

  9. 云客Drupal源码分析之前端js中的翻译

    从本主题开始<云客Drupal源码分析>系列将连续发布和前端js相关的内容,如果您对JavaScript还不熟悉或者需要来一次系统性的整理回顾,在此云客为您准备了以下资料: <PHP ...

最新文章

  1. 客快物流大数据项目(六):Docker与虚拟机的形象比喻及组件介绍
  2. 30段极简Python代码:这些小技巧你都Get了么(附代码链接)
  3. 模版方法模式/Template Method
  4. C++/CLI思辨录之代理构造函数
  5. linux下源码安装vim,ubuntu 源码编译安装最新的vim 8.0
  6. html编写组织结构,编写模块化的CSS:CSS文件组织结构
  7. python3安装setuptools步骤_linux环境下的python安装过程(含setuptools)
  8. 职业学校教的计算机技术,浅谈对职业学校计算机专业数据库教学
  9. java.util.concurrent.Future基础
  10. C语言printf()、sprintf()、vsprintf() 的区别与联系
  11. map-reduce 、map、reduce
  12. css3-13 css3的3D动画如何实现
  13. ios 模拟器添加经纬度_iOS 微信双开来了,但我不建议你使用
  14. C语言程序流程图switch,C语言流程控制之switch语句详解
  15. 618号外:MS08067安全实验室也做安全培训了
  16. 单维度量表验证性因子分析_探索性因子分析(EFA)和验证性因子分析(CFA)
  17. 深度学习分类问题中accuracy等评价指标的理解
  18. 简单的E_mail发送
  19. ppt倒计时器制作方法
  20. 构建orangePi r1 plus (RK3328)系统的整个过程

热门文章

  1. 新零售:从上云到云原生 Serverless
  2. 微信“支付”页全国多地上线“出行服务”,已覆盖108城
  3. 灰度测试试验流量“洗牌”
  4. OpenStack精华问答 | OpenStack的目标是什么?
  5. 混合云发展之路:前景广阔,巨头混战
  6. oom 如何避免 高并发_【面试】如何避免OOM的发生
  7. linux ps2键盘驱动,通用键盘鼠标模拟(包括USB和PS2)
  8. mysql 别名 metadata_获取数据库元数据:DatabaseMetaData与ParameterMetaData与ResultSetMetaData...
  9. shell脚本报错“^M: bad interpreter”解决方法
  10. ETL异构数据源Datax_datax-web安装部署_10