状态管理与导航守卫

vuex是什么?

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

为什么要用vuex?

1.进行统一的状态管理,解决不同组件共享数据的问题。
2.不同视图需要变更同一状态的问题。
3.使用vuex之后,状态变化更加清晰

如何使用vuex?

1.安装引入 npm install vuex --save
2.注册到vue中

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

3.实例化vuex的store

export default new Vuex.Store({
    state: {},
    getters: {},
    mutations: {},
    actions: {},
    modules: {}
})

4.挂载在vue实例上

new Vue({
  store,
  render: h => h(App)
}).$mount('#app')

5.在组件中就可以通过this.$store对vuex进行操作。

state 存放初始数据

 state: {
        count: 1 
  },
  1. 组件中去取state的值,通过this.$store.state
  2. 或者可以通过计算属性取得,mapState辅助函数,可以简化操作:
import {mapState} from "vuex";
computed: {
      ...mapState({
          // 传字符串参数 'count' 等同于 `state => state.count`
          count: 'count',
          // 箭头函数可使代码更简练
          count: state => state.count,
      })
},

getters 对state中的数据进行初加工(派生),类似vue中的computed,进行缓存

 state: {
        arr: [1, 2, 3, 4]
  },
  getters: {
        // 参数一:state 参数二:其他 getter
        changeArr(state,getters) {
            return state.arr.map(item => item + 1)
        }
  },
   
注意,getter 在通过属性访问时是作为 Vue 的响应式系统的一部分缓存其中的。
  1. 取getters中的值,通过this.$store.getters,
  2. 或者通过计算属性取,getters也有辅助函数mapGetters, 用法和mapState一致。
import {mapGetters} from 'vuex'
// 1、
...mapGetters([
    'changeCount',
        // ...
])
// 2、
...mapGetters({
    changeCount: 'changeCount'
    // ...
})

mutations 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation 同步修改

//定义mutation
state: {
    count: 1,
},
mutations: {
   // 参数一:state 参数二:传入额外的参数
    increment(state, payload) {
          state.count = payload.count
    },
},
//调用mutation
// 1、普通方式
this.$store.commit('increment', {count: 10})
// 2、对象风格的提交方式
 this.$store.commit({
        type: 'increment',
        count: 10
})
  1. 在组件中提交 Mutation
    你可以在组件中使用 this.$store.commit(‘xxx’) 提交 mutation,或者使用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用(需要在根节点注入 store)。
import { mapMutations } from 'vuex'
methods:{
  ...mapMutations([
      'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment', {count: 10})`
  ]),
  ...mapMutations({
        add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
    }),
},
this.increment({count: 10})
this.add({count: 10})

actions action类似于mutation,不同的是action可以包含异步操作 action不能直接修改state,如果想修改state的话,需要触发mutation

//定义action
 state: {
    count: 0
  },
  mutations: {
    increment (state,payload) {
      state.count = payload.count 
    }
  },
  actions: {
    // 第一个参数通过context(上下文环境)可以触发mutation,触发action,获取state、getter等操作
    // 第二个参数就是我们传递过来的参数
     incrementAsync(context, payload) {
          setTimeout(() => {
              context.commit('increment', payload)
          }, 1000);
      }
  }
//调用action
//  1、普通方式
this.$store.dispatch('incrementAsync', {count: 10})
// 以对象形式分发
this.$store.dispatch({
  type: 'incrementAsync',
  count: 10
})

在组件中提交 action
你在组件中使用 this.$store.dispatch(‘xxx’) 分发 action,或者使用 mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用(需要先在根节点注入 store):

import { mapActions } from 'vuex'
methods: {
      ...mapActions([
          'incrementAsync', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment', {count: 10})`
      ]),
      ...mapActions({
          add: 'incrementAsync' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
      }),
},
this.incrementAsync({count: 10})
this.add({count: 10})

modules

定义module
// index.js中手动引入modules
import app from './modules/app'
modules: {
  app
}
<!--   app.js -->
  const app = {
  state: {
    num: 10
  },
  // 默认state就是有命名空间,
  // 如果想给mutation和action也加上命名空间的话,这里设置模块的namespaced:true
  getters: {},
  mutations: {
      changeNum(state, payload) {
        state.num = payload.num
      }
  },
  actions: {}
}

export  default  app
调用module
// 使用命名空间
this.$store.commit("app/changeNum", {num: 10})
// 未使用
this.$store.commit("changeNum", {num: 10})

vuex持久化存储

在开发的过程中, vuex数据刷新页面会初始化。像用户信息(名字,头像,token)需要vuex中存储且需要浏览器本地存储来实现持久化存储。

安装 npm install vuex-persistedstate --save

引入 import createPersistedState from ‘vuex-persistedstate’

使用

export default new Vuex.Store({

plugins: [
        createPersistedState(),
 ],
// 默认存储到localStorage,如果想要存储到sessionStorage,配置如下
plugins: [    
      // 把vuex的数据存储到sessionStorage    
      createPersistedState({      
          storage: window.sessionStorage,    
      }),  
  ],
// 持久化所有的state,如果想要存储指定的state,配置如下
plugins: [    
      // 把vuex的数据存储到sessionStorage    
      createPersistedState({      
          storage: window.sessionStorage,      
          reducer(val) {        
              return {          
                   // 只存储state中的count          
                   count: val.count       
              }      
          }    
       }),  
  ],
})

导航守卫(路由守卫)

什么是导航守卫

vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。这里有很多方式植入路由导航中:全局的,单个路由独享的,或者组件级的。

全局前置守卫

const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  }
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

router.beforeEach((to, from,next) => {
  // ...
  // 返回 false 以取消导航
  return false
})

当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于等待中。
每个守卫方法接收三个参数:
to: 即将要进入的目标
from: 当前导航正要离开的路由
next:next 是函数
注意:确保 next 函数在任何给定的导航守卫中都被严格调用一次。它可以出现多于一次,但是只能在所有的逻辑路径都不重叠的情况下,否则钩子永远都不会被解析或报错

全局后置钩子

你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:

router.afterEach((to, from, failure) => {
    // console.log(failure)
    console.log(to,from,failure)
})
// 它们对于分析、更改页面标题、声明页面等辅助功能以及许多其他事情都很有用。

路由独享的守卫

你可以在路由配置上直接定义 beforeEnter 守卫:这些守卫与全局前置守卫的方法参数是一样的。

const router = new VueRouter({
  routes: [
    {
      path: '/about',
      component: About,
      beforeEnter: (to, from, next) => {
        // ...再进入当前路由之前要发生的事
      }
      // 路由元信息,作标识用(当路径path太长,可以用meta)
      meta:{
        isLogin:true
      }
    }
  ]
})

路由标识meta

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值