Vue2.0基础-温故而知新-part3

175 阅读3分钟

3.1 vuex(P105~P114)

  • 定义:一个Vue插件;用于实现集中式状态(数据)管理;实现任意组件间通信。
  • vuex不属于任何组件(在App之外)
  • vuex工作原理: image.png
  • 原理流程:
    1. 组件中调用vc.$store.dispatch('动作类型', 数据)
    2. Actions对象中,调用'动作类型'对应的函数
    3. 上述的函数中调用commit('动作类型', 数据)
    4. Mutations对象中,调用'动作类型'对应的函数
    5. 上述函数中会改变State对象中的数据
    6. (自动)渲染组件
  • store管理Actions Mutations State
  • 使用流程:
    1. npm安装
    2. src/store/index.js 中写store对象(包含actions mutations state对象)
    3. index.js中引入Vue和Vuex,并使用Vue.use(Vuex)
    4. main.js引入store,创建vm时使用store配置项
    //index.js文件:
    import Vue from "vue"
    import Vuex from "vuex"
    Vue.use(Vuex)
    const actions = {}
    const mutations = {}
    const state = {}
    const getters = {}
    
    export default new Vuex.Store({
      actions,
      mutations,
      state,
      getters
    })
    
  • actions中的回调函数:actionCallBack(context, value),context可以理解为精简版store,有commit方法,value为dispatch触发回调时传入的数据(或者后端传来的数据)
    • 所有的业务逻辑放在actions中
    • context.dispatch(),可以调用其他的action回调
  • mutations中的回调函数:mutationCallBack(state, value),可以直接拿到state
  • getters配置项,用于加工state中的数据,内配置带返回值的函数,与computed相同
  • mapState与mapGetters:映射state或者getters中的数据生成计算属性,使用前需要先在vue文件中引入(目的是方便书写,不用每次调用都写$store.state)
import {mapState, mapGetters} from 'vuex'
...
    computed:{
    //对象写法:从$store.state中拿到sum变量,映射给a
      ...mapState({
        a: 'sum',
        b: 'avg'
      })
    //数组写法:从$store.getters中拿到sum和avg变量,映射给同名计算属性(此时必须保证两者名称一致) 
      ...mapGetters(['sum', 'avg'])
    }
  • mapMutations与mapActions:在methods中生成同mutations或者actions对话的方法,与mapState类似,也有对象写法与数组写法,注意:传递参数问题。(mapActions相当于$store.dispatch,mapMutations相当于store.commit)

3.2 vuex模块化(P115~P116)

  • 按功能划分模块,每个模块(对象)都有自己的一套actions、mutations、state等
//两个模块化的vuex实例对象(也可写单独的js文件,之后在store.js引入 ),内分别有state、mutations、actions和getters
    const moduleA = {}
    const moduleB = {}
    export default new Vuex.store({
      moduleA,
      moduleB
    })
  • 在使用state时
    this.$store.state.moduleA.list
  • 在使用getters时
    this.$store.getters[moduleA/updateList]
  • 在使用commit或dispatch时
//调用moduleA模块中mutations里的CHANGE方法
    this.$store.commit('moduleA/CHANGE', value)
  • namespaced命名空间配置项:如果想用四个map方法的制定模块对象,需要在模块对象中配置namespaced为true。
//第一个参数制定模块对象,第二个参数与正常使用map方法时一样
    ...mapState('moduleA', [])

3.3 路由 vue-router(P117~P127)

  • route路由 是指一对key-value的对应关系
  • vue-router是插件,在main.js中引入并use,这样vm中可以加入新的配置项vue-router
  • 使用流程:
    • main.js中引用并使用vue-router
    • src下新建router文件夹,在其中的index.js文件中配置相关内容
    import VueRouter from 'vue-router'
    //引入组件
    import About from '../pages/About.vue'
    import Home from '../pages /Home.vue'
    //配置路由对象
    export default new VueRouter({
      routes:[
        {
          path: '/about',
          component:About
        },
        {
          path: '/home',
          component:Home
        }
      ]
    })
    
    • 在main.js中引入router,并添加在vm的配置项中
    • 使用router-link标签,配合to属性使用(以a标签形式表现在页面中)实现不同页面切换的触发点
    • 使用router-view标签,指定组件的呈现位置
  • 不显示的路由组件被销毁了
  • 每个路由组件都有自己的$route对象
  • 多级路由:在children配置项中配置,router-link标签中的to属性要写完整的路由路径
//Home路由组件中有子路由,在children配置项中配置
{
  path: '/home',
  component:Home,
  children:[
    {
    //子路由的path不加/
      path:...,
      component:...
    }
  ]
}
  • 路由传参:
    • query参数:传递的参数在路由组件(接收方)的$route.query对象中保存
    //to的字符串写法:在路径的后面接?,之后是要传递的参数
    <router-link :to="`/home/person?id=${123}&name=${456}`"> </router-link>
    //to的对象写法:推荐使用对象写法
    <router-link :to="{
      path:'/home/person',
      query:{
        id: 123,
        name: 456
      }
    }">
    </router-link>
    
    • params参数:传递的参数在路由组件(接收方)的$route.params对象中保存。需要在配置时的path配置项中提前声明:
    {
      name
      path:"/home/person/:id/:name", //使用占位符声明接收的参数
      component: Person
      children
    }
    
    //to的字符串写法:在路径的后面接/,之后是要传递的参数
    <router-link :to="`/home/person/${123}/${456}`"> </router-link>
    //to的对象写法:注意,此处一定要用name配置
    <router-link :to="{
      name:'person',
      params:{
        id: 123,
        name: 456
      }
    }">
    </router-link>
    
  • 命名路由:用于简化path,在路由组件中使用name配置项。使用时,to必须是v-bind,并且必须是对象形式。
  • props配置项:用于简便传参,接收参数的组件要写props配置项
{
  name
  path
  component:Person
  //第一种写法:props值为对象,对象中所有key-value组合都会传给Person组件
  props:{id: 123, name: 456}
  //第二种写法:props值为布尔值,当props为true时,把所有params参数(不能是query参数)通过props传给Person组件
  props:true
  //第三种写法:props值为函数,返回的对象中每一组key-value都传给Person组件
  props(route){
    return {
      id: route.query.id,
      name: route.query.name
    }
  }
}
  • router-link的push(默认)模式和replace(模式):控制浏览器历史记录模式
  • 编程式路由导航:不使用router-link实现路由跳转,更加灵活
//利用$router的两个API
this.$router.push({
//配置项和router-link的to的对象写法一致
  name
  params
})
this.$router.replace({
//配置项和router-link的to的对象写法一致
  name
  params
})
  • 缓存路由组件:让不展示的路由组件保持挂载不被销毁。
  <keep-alive :include="['组件名']">
    <router-view></router-view>
  </keep-alive>
  • 路由独有的生命周期钩子
    • activated()激活
    • deactivated()失活

3.4 路由守卫(P128~P132)

  • 路由守卫作用是对路由进行权限控制:例如访问组件时校验
  • 全局前置路由守卫
//在router/index.js路由配置文件中配置
  router.beforeEach((to, from, next)=> {
  //to包含目标路由信息,from包含来源路由信息
  //next():放行
  })
  • 全局后置路由守卫
  router.afterEach((to, from)=> {
  //to包含目标路由信息,from包含来源路由信息
  })
  • 路由配置中的meta属性设置路由元信息,在守卫中可以拿到
  • 独享路由守卫:写在路由配置项内,只有前置没有后置
    {
      name
      path
      component: Person
      children
      //独享守卫
      beforeEnter(to,from,next){
      
      }
    }
    
  • 组件内路由守卫:在组件内写(与其他生命周期函数在同一位置)
    • beforeRouteEnter:通过路由规则,进入该组件时调用
    • beforeRouteLeave:通过路由规则,离开该组件时调用
  beforeRouteEnter(to,from,next){
    next()
  }
  beforeRouteLeave(to,from,next){
    next() 
  }

3.5 路由两种工作模式:hash与history(P133)

  • 在route配置文件中的mode配置项修改
  • hash模式:url中带有#,#及其后面内容为哈希值,不发送给服务器
  • history模式:需要后端用中间件配合避免404问题