vue全家桶初级学习

143 阅读1分钟

学习目标

  1. 掌握vue-route用法和技巧
  2. 掌握vue-route实现原理
  3. 掌握vuex理念和核心用法
  4. 理解vuex实现原理

知识要点

  1. 路由配置、导航、传参、首位
  2. vuex核心用法、模块化
  3. 混入mixins
  4. vue插件
  5. 渲染函数

动态路由

我们经常需要把某种模式匹配到的的所有路由,全部映射到一个组件中

传递路由组件参数:
{path:'/detail/:id',component:Detail,props:true}
组件以属性的方式获取
export default {props:'id'}

可以有效解耦,增加组件的通用性

路由守卫

  • 全局守卫,route.js
//路由配置
{
    path:'/about',
    name:'about',
    meta:{auth:true},//需要认证
    component:()=>import ('/view/About.vue')
}
//守卫
router.beforeEach((to,from,next)=>{
    //要访问/about 且未登录需要去登录
    if(to.meta.auth&&!window.isLogin){
        if(window.confirm('请登录')){
            window.isLogin=true;
        	next()//登陆成功,继续
        }else{
        	next('/')//放弃登录,回首页
        }
    }else{
        next()//不需要登陆,继续
    }
})

权限配置

可由后台设置配置权限可访问的路由,通过异步获取路由,再利用router.addRoutes()加入到路由中

面包屑

利用$route.matched可得到路由匹配数组,按顺序解析可得到路由层次关系

watch:{
    $route(){
        //[{name:'home'},{name:'list'}]
        console.log(this.$route.matched);
        this.crumbData=this.$route.matched.map(m=>m.name)
    }
}

vue-router实现原理

  • 实现插件
  • url变化监听
  • 路由配置解析:{'/':Home}
  • 实现全局组件:router-link router-view

具体实现

import Home from './App.vue';
import Vue from 'vue'
import { render } from 'less';
class VueRoute {
  constructor(options){
    this.$options=options;
    this.routeMap={}

    //路由响应式
    this.app=new Vue({
      data:{
        current:'/'
      }
    })
  }
  init(){
    this.bindEvents();//绑定监听事件,监听url的变化
    this.createRouteMap(this.$options);//解析路由配置
    this.initComponent();//实现两个组件

  }
  bindEvents(){
    window.addEventListener('load',this.onHashChange.bind(this))
    window.addEventListener('onHashChange',this.onHashChange.bind(this))
  }
  onHashChange(){
    this.app.current=window.location.hash.slice(1)||'/'
  }
  createRouteMap(options){
    options.routes.forEach(item => {
      this.routeMap[item.path]=item.component;
    });
  }
  initComponent(){
    Vue.component('router-link',{
      props:{
        to:String
      },
      render(h){
        return h('a',{attrs:{href:'#'+this.to}},[this.$slot.default])
      }
    })

    Vue.component('router-view',{
      render:(h)=>{
        const comp=this.routeMap[this.app.current].component
        return h(comp)
      }
    })
  }
}
VueRoute.install = function (Vue) {
  Vue.minxin({
    beforeCreate() {
      if (this.$Options.router) {
        Vue.prototype.$router = this.$Options.router;
        this.$Options.router.init();
      }
    }
  })
}
Vue.use(VueRoute);

export default new VueRoute({
  routes: [{
    path: '/',
    component: Home
  }]
})

Vuex状态管理

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。

vuex

核心概念

  • state 驱动应用的数据源;
  • mutations 更改状态的函数;
  • actions 异步操作;
  • store 包含以上概念的容器

状态和状态变更

state保存数据状态,mutations用于修改状态,store.js

export default new Vuex.Store({
    state:{count:0},
    mutations:{
        increament(state,n=1){
            state.count+=n
        }
    }
})

派生状态-getters

从state派生出新的状态,类似计算属性

export default new Vuex.Store({
    state:{count:0},
    mutations:{
        increment(state,n=1){
            state.count+=n
        }
    },
    getters:{
        score(state){
            return `共扔出:${state.count}`
        }
    }
})

使用方式:

<span>{{$store.getters.score}}</span>

异步操作-actions

复杂的业务逻辑,类似于controller

actions:{
    incrementAsync(commit,dispatch){
        setTimeout(()=>{
            commit('increment',2)
        },1000)
    }
}

vuex原理解析

借用vue本身的数据响应机制使state响应化,从而使state变化立刻响应在依赖的视图中

  • 实现插件
  • 实现三个方法:state/mutations/actions/getters
  • 创建store
  • 数据的响应式
let Vue;
class Store {
  constructor(options) {
    this.state = new Vue({
      data = options.state
    })
    this.mutations = options.mutations;
    this.actions = options.actions;
  }
  commit = (type, arg) => {
    this.mutations[type](this.state, arg);

  }
  dispatch(type, arg) {
    this.actions[type]({
      commit: this.commit,
      state: this.state
    }, arg)
  }
}

function install(_Vue) {
  Vue = _Vue;
  Vue.mixin({
    beforeCreate() {
      if (this.$options.store) {
        Vue.prototype.$store = this.$option.store;

      }
    }
  })
}

export default {
  store,
  install
}