【小慕读书】—— 后台管理系统学习:Vuex 和 Vue-router 进阶

vue

前言:最近在学习Vue+Element UI+Node.js小慕读书中后台管理系统开发课程,这里对学习过程作个笔记,方便自己和大家翻阅。


 一、Vuex 原理解析

Vuex 的原理关键:使用 Vue 实例管理状态

<body>

<div >{{data}}</div>

<div >{{data2}}</div>

<div >

<button @click="change">change</button>

</div>

<script>

function registerPlugin(Vue) {

const vuex = {}

vuex._vm = new Vue({ //_vm是Vue实例

data: {

message: 'hello vue.js'

}

})

vuex.state = vuex._vm

vuex.mutations = {

setMessage(value) {

vuex.state.message = value

}

}

function init() {

this.$store = vuex

}

Vue.mixin({ //全局的mixin

beforeCreate: init

})

}

Vue.use(registerPlugin)

new Vue({

el: '#root',

computed: {

data() {

return this.$store.state.message

}

}

})

new Vue({

el: '#root2',

computed: {

data2() {

return this.$store.state.message

}

}

})

new Vue({

el: '#root3',

methods: {

change() {

const newValue = this.$store.state.message + '.'

this.$store.mutations.setMessage(newValue) //Vue响应式 前两个Vue实例的message都会变化

}

}

})

</script>

</body>

二、router" title="vue-router">vue-router 实现原理

vue-router 实例化时会初始化 this.history,不同 mode 对应不同的 history

constructor (options: RouterOptions = {}) {

this.mode = mode

switch (mode) {

case 'history':

this.history = new HTML5History(this, options.base)

break

case 'hash':

this.history = new HashHistory(this, options.base, this.fallback)

break

case 'abstract':

this.history = new AbstractHistory(this, options.base)

break

default:

if (process.env.NODE_ENV !== 'production') {

assert(false, `invalid mode: ${mode}`)

}

}

}

这里以 HashHistory 为例,vue-router 的 push 方法实现如下: (实际调用的是Hashhistory的push方法) 

push (location: RawLocation, onComplete?: Function, onAbort?: Function) {

// $flow-disable-line

if (!onComplete && !onAbort && typeof Promise !== 'undefined') {

return new Promise((resolve, reject) => {

this.history.push(location, resolve, reject)

})

} else {

this.history.push(location, onComplete, onAbort)

}

}

HashHistory 具体实现了 push 方法:  

function pushHash (path) {

if (supportsPushState) {

pushState(getUrl(path))

} else {

window.location.hash = path

}

}

对路由的监听通过 hash 相应的事件监听实现:  

window.addEventListener(

supportsPushState ? 'popstate' : 'hashchange',

() => {

const current = this.current

if (!ensureSlash()) {

return

}

this.transitionTo(getHash(), route => {

if (supportsScroll) {

handleScroll(this.router, route, current, true)

}

if (!supportsPushState) {

replaceHash(route.fullPath)

}

})

}

)

除此之外,vue-router 还提供了两个组件:  

Vue.component('RouterView', View)

Vue.component('RouterLink', Link)

三、vue-router 路由守卫

创建 router.js:  

import Vue from 'vue'

import Route from 'vue-router'

import HelloWorld from './components/HelloWorld'

Vue.use(Route)

const routes = [

{ path: '/hello-world', component: HelloWorld }

]

const router = new Route({

routes

})

export default router

在 main.js 中引用 router,并加入 vue 实例:  

import router from './router'

new Vue({

render: h => h(App),

router

}).$mount('#app')

四、全局守卫

进入每一个路由都会触发的钩子函数

注意:因为写在vue-router中,所以全局守卫都是没有办法获得Vue实例的。

//router.js
router.beforeEach((to, from, next) => { //当路由进入之前可以触发的操作

console.log('beforeEach', to, from)

next()

})

router.beforeResolve((to, from, next) => { //当路由被解析之前被调用 Vue2.5新特性

console.log('beforeResolve', to, from)

next()

})

router.afterEach((to, from) => { //当路由进入之后可以触发的事件

console.log('afterEach', to, from)

})

 整个路由守卫执行是在组件生命周期函数之前的:

 beforeEach(全局守卫)、befforeResolve(全局守卫)、afterEach(全局守卫)

 beforeCreate、created、beforeMount、mouted

五、局部守卫

只适合在当前路由使用,是局部的路由守卫。(写在和组件的生命周期函数同一级)

1.to:表示当前路由,即要进入的路由

2.from:表示从哪来的,

3.next() 表示下一步要干啥,next('/addGoods')就表示下一步,调到路由 /addGoods

//A.vue
beforeRouteEnter (to, from, next) { //在需要进入的组件中调用

// 不能获取组件实例 `this`, 因为在组件生命周期beforeCreate之前

console.log('beforeRouteEnter', to, from)

next()

},

beforeRouteUpdate (to, from, next) { //在复用(更新)的组件中调用

console.log('beforeRouteUpdate', to, from)

next()

},

beforeRouteLeave (to, from, next) { //在离开的组件中调用

console.log('beforeRouteLeave', to, from)

next()

}

  •  进入组件:beforeEach(全局守卫)、beforeRouteEnter(局部守卫)、beforeResolve(全局守卫)、afterEach(全局守卫)、beforeCreate、created、beforeMount、mounted

  • 更新组件:beforeEach(全局守卫)、beforeRouteUpdate(局部守卫)、beforeResolve(全局守卫)、afterEach(全局守卫)
  • 离开组件:beforeRouteLeave(局部守卫)、beforeEach(全局守卫)、beforeResolve(全局守卫)、afterEach(全局守卫)、 beforeDestory

六、路由元信息

通过 meta 定义路由元信息  

const routes = [

{ path: '/a', component: A, meta: { title: 'Custom Title A' } }

]

使用 meta 信息动态修改标题

(和路由相关的功能,推荐放在路由的全局守卫中实现)  

router.beforeEach((to, from, next) => {

console.log('beforeEach', to, from)

if (to.meta && to.meta.title) {

document.title = to.meta.title

} else {

document.title = 'default title'

}

next()

})

七、路由 API

使用 router.addRoutes 动态添加路由

使用场景:菜单路由的权限赋值 

addRoute() {

this.$router.addRoutes([{

path: '/b', component: B, meta: { title: 'Custom Title B' },

}])

}

此时可以访问到 B 组件  

<router-link to='/b'>to B</router-link>


注:项目来自慕课网    

以上是 【小慕读书】—— 后台管理系统学习:Vuex 和 Vue-router 进阶 的全部内容, 来源链接: utcz.com/z/379016.html

回到顶部