手记

【学习打卡】第1天 Vue Element+Node.js开发企业通用管理后台系统(第4章)

课程名称:Vue Element+Node.js开发企业通用管理后台系统
课程章节: 第4章 Vuex和Vue-router进阶
主讲老师:Sam
课程内容:

今天学习的内容包括:

  • vuex 原理解析
  • vue-router 原理解析
  • vue-router 路由守卫
  • vue-router 路由元信息

主要围绕 vue 全家桶的 vuex 和 vue-router 进阶内容展开。

课程收获:

  1. vuex 原理解析
    vuex 的原理关键:使用 Vue 实例进行状态管理
<html>
  <head>
    <title>vuex 原理解析</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="root">{{data}}</div>
    <div id="root2">{{data2}}</div>
    <div id="root3">
      <button @click="change">change</button>
    </div>
    <script>
      function registerPlugin(Vue) {
        //定义vuex对象
        const vuex = {}
        //_vm属性是一个vue实例
        vuex._vm = new Vue({
          data: {
            message: 'hello vue.js'
          }
        })
        //state就是vue实例
        vuex.state = vuex._vm
        //定义mutations
        vuex.mutations = {
          setMessage(value) {
            vuex.state.message = value
          }
        }
        //定义初始化方法
        function init() {
          //在每个实例下都挂载一个 $store 属性
          this.$store = vuex
        }
        //对所有vue实例,都在beforeCreate调用init方法
        Vue.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)
          }
        }
      })
    </script>
  </body>
</html>

上述示例中,模拟了3个 vue 实例,帮助理解 vuex 状态管理应用。并创建了一个简易的 vuex 对象,通过在对象上挂载属性

  1. 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}`)
        }
    }
}

在监听路由变化的时候,主要是对原生事件的监听:

  • hash 模式
window.addEventListener('hashchange',()=>{
   this.current=window.location.hash.slice(1)
})
  • history 模式
window.addEventListener("popstate",()=>{
    this.current = location.pathname
})

vue-router 还提供了两个组件 <router-view><router-link>。使用 vue 所开发的页面是一个单组件页面,只包含了 App.vue ,在 App.vue 里面通过<router-view>来切换组件。

  1. vue-router 路由守卫
    所谓路由守卫就是路由的钩子函数,它和组件的生命周期钩子函数类似。路由守卫可以分为:全局守卫和局部守卫。
  • 全局守卫即每个路由都会触发。
router.beforeEach((to, from, next) => {
  console.log('beforeEach', to, from)
  next()
})

router.beforeResolve((to, from, next) => {
  console.log('beforeResolve', to, from)
  next()
})

router.afterEach((to, from) => {
  console.log('afterEach', to, from)
})

如设置了全局守卫,并在组件中设置了组件的生命周期钩子函数,执行过程会发现路由会在组件的生命周期钩子函数前执行。

  • 局部守卫(会写在 .vue 文件中)
beforeRouteEnter (to, from, next) {
  // 不能获取组件实例 `this`
  console.log('beforeRouteEnter', to, from)
  next()
},
//当前组件发生变化的时候触发(如url参数变化)
beforeRouteUpdate (to, from, next) {
  console.log('beforeRouteUpdate', to, from)
  next()
},
beforeRouteLeave (to, from, next) {
  console.log('beforeRouteLeave', to, from)
  next()
}

如设置了局部守卫,并在组件中设置了组件的生命周期钩子函数,执行过程为:beforeRouteEnter->beforeCreate->created->beforeMount->mounted。
4. 路由元信息
路由元信息的主要作用为当前组件增加一些额外的参数信息,这个信息并不是通过 url 参数传递过来。

场景一:动态设置 title

  • 通过 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()
})

除了视频中演示的这种场景之外,日常还会在 meta 元信息中设置权限控制。

routes: [{
        path: '/login',
        name: 'login',
        meta: {
         roles: ['admin', 'user']
        },
        component: () => import('@/components/Login')
    }]

最后,附上一张课程学习截图,ending~

0人推荐
随时随地看视频
慕课网APP