日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

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

發(fā)布時(shí)間:2024/9/27 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 vuex 源码分析_前端入门之(vuex-router-sync解析) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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

發(fā)布時(shí)間:2018-11-14 13:31,

瀏覽次數(shù):513

, 標(biāo)簽:

vuex

router

sync

前言:vue全家桶的內(nèi)容我們已經(jīng)研究過了vuex、vue-router,有興趣的童鞋可以去看看我之前的兩個(gè)系列的文章vuex源碼解析一

、vue-router全解析一

,之前結(jié)合項(xiàng)目分析vuex的時(shí)候,當(dāng)我們需要在vuex的action中處理路由跳轉(zhuǎn)的時(shí)候,沒認(rèn)識vuex-router-sync的時(shí)候,我一般都是直接拿到router對象,然后稍微封裝了一下進(jìn)行跳轉(zhuǎn)的,哈哈~~

在看vue的github官網(wǎng)的時(shí)候不小心看到了vuex-router-sync,哈哈!!

才知道原來官方已經(jīng)有一個(gè)工具把store跟router連接起來了,翻了一下vuex-router-sync的源碼才知道原來還可以這么操作?于是打算把自己所理解的內(nèi)容記錄下來,歡迎指正,大牛勿噴!!!

我們直接執(zhí)行:

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內(nèi)容:

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

我們可以看到,在store的route對象其實(shí)就是我們r(jià)outer中的currentRoute對象(當(dāng)前路由).

好啦~

到這我們小伙伴可能要疑問啦,我直接用this.$router.route也可以拿到currentRoute對象啊,為啥還這么復(fù)雜呢?這樣做又有啥好處呢?不急不急,我們直接看看它的源碼來研究下它的功能哈~~

我們找到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的庫啊~~~ 小伙伴是不是跟我一樣驚訝呢?

小伙伴莫及哈,代碼雖少,但其中的思路跟用法還是值得我們學(xué)習(xí)的,這也是我為啥寫這篇文章的原因了~ 廢話不多說了,我們開始帶著源碼往下走.

首先是在我們的store中注冊了一個(gè)module,名字默認(rèn)為“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中提供了一個(gè)叫“ROUTE_CHANGED”的mutation處理方法,然后還把router對象中的currentRoute保存在了state中,這也是我們?yōu)槭裁茨軌蛲ㄟ^this.$store.state.route拿到currentRoute的原因.

然后就是監(jiān)聽store中的route對象的變化了,當(dāng)route發(fā)生變化并且當(dāng)前路由名字不等于需要跳轉(zhuǎn)到路由的時(shí)候,直接通過router的push方法進(jìn)行跳轉(zhuǎn)頁面:

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是一個(gè)概念,也就是檢測某個(gè)屬性的變化,然后回調(diào).

最后通過router的全局后置鉤子函數(shù)監(jiān)聽當(dāng)前路由對象,修改store中的當(dāng)前state(當(dāng)前路由對象):

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

好啦,整個(gè)庫的源碼算是分析完畢了,小伙伴是不是還是很疑問呢? 這東西怎么用呢? 我們接下來結(jié)合一個(gè)demo來用用它~

一般來說項(xiàng)目為了讓頁面跟數(shù)據(jù)邏輯分離出來,一般一些邏輯處理都在vuex的action中進(jìn)行了,我就簡單結(jié)合之前的博客中的demo操作了~

我們運(yùn)行項(xiàng)目看到有一個(gè)a頁面:

我是a頁面

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

} }

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

然后我們項(xiàng)目可能有這么一個(gè)需求:“當(dāng)點(diǎn)擊a頁面的某個(gè)按鈕的時(shí)候,我們會調(diào)后臺接口,然后再跳轉(zhuǎn)某個(gè)具體的頁面~”

我們在a頁面放一個(gè)“登錄”按鈕,然后點(diǎn)擊去登錄,登錄成功跳轉(zhuǎn)到登錄成功頁面:

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

我們直接模擬一下登錄,然后跳轉(zhuǎn)到b頁面

好啦!! 我們vuex-router-sync就分析到這啦~~

歡迎入群,歡迎交流,qq群鏈接:

總結(jié)

以上是生活随笔為你收集整理的vuex 源码分析_前端入门之(vuex-router-sync解析)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。