状态管理与导航守卫

为什么要用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) => {
   
        // ...
      }
    }
  ]
})

相关推荐

  1. 状态管理导航守卫

    2024-01-29 10:50:02       33 阅读
  2. React导航守卫(V6路由)

    2024-01-29 10:50:02       38 阅读
  3. (已解决)什么是vue导航守卫

    2024-01-29 10:50:02       32 阅读
  4. VueRouter的编程式导航导航守卫

    2024-01-29 10:50:02       35 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-29 10:50:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-29 10:50:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-29 10:50:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-29 10:50:02       18 阅读

热门阅读

  1. Ubuntu系统桌面卡死,解决办法

    2024-01-29 10:50:02       35 阅读
  2. 计算机视觉(CV)技术的优势和挑战

    2024-01-29 10:50:02       31 阅读
  3. 【漏洞复现】金蝶云星空-AppDesigner-反序列化-rce

    2024-01-29 10:50:02       35 阅读
  4. Vue3+Echarts实现实时曲线及开始与暂停功能

    2024-01-29 10:50:02       31 阅读
  5. Qlik Sense : IntervalMatch(离散匹配)

    2024-01-29 10:50:02       29 阅读
  6. Leetcode 3021. Alice and Bob Playing Flower Game

    2024-01-29 10:50:02       36 阅读
  7. 记录 | ubuntu查看系统信息如系统版本、cpu信息

    2024-01-29 10:50:02       33 阅读
  8. ubuntu 添加 sudo 权限

    2024-01-29 10:50:02       31 阅读