Vuex 终极秘籍总结

63 篇文章 4 订阅
28 篇文章 0 订阅

Vuex 终极秘籍总结

一、什么是Vuex

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

你可以理解 Vuex 为全局变量,与 data 不同的是,Vuex 的值刷新不会改变、所有页面均可使用、调用 Vuex 的方法和属性

二、Vuex 核心属性
  • state 相当于data
  • mutations 相当于 methods (只能写同步)
  • action 相当于 methods中的异步方法 (只能写异步)
  • getters 相当于 computed 计算属性
  • modules 模块化思想**(后边着重讲)**
三、项目中使用 Vuex
1. Vuex 代码
import Vue from 'vue'
import Vuex from 'vuex'
import modules from './modules' // 模块化部分,暂时忽略,后期在讲
import getters from './getters' // 模块化部分,暂时忽略,后期在讲
Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    count:0
  },
  // 此函数下不可写异步代码
  mutations: {
    // 相当于methods方法
    add (state) {
      // mutations方法中可以接收两个参数 state 和 val
      // state 用来承接上下文,调用方法可不传,默认第一个参数为 state
      // val 即修改 state 中的值
      state.count++
    },
    addX (state, x) {
      state.count += x
    },
    sub (state) {
      state.count--
    },
    addStore (state, step) {
      state.count -= step
    },
    addMoreSync (state, step) {
      state.count += step
    }
  },
  // 此函数下写异步方法
  actions: {
    addAsync (content) {
      // actions 类似于 mutations,都可以接收两个参数
      // content 承接上下文, val 用来接收实参
      // actions 中的方法需要使用 commit 调用 mutations 中的方法来修改 state 中的值
      setTimeout(() => {
        content.commit('add')
      }, 1000)
    },
    addMoreAsync (content, step) {
      setTimeout(() => {
        content.commit('addMoreSync', step)
      }, 1000)
    }
  },
  // 为方便大家在非模块化时更容易理解 getters 所以这里定义了两个 getters 函数
  getters:{
    getterCount (state) {
      return state.count + 'Vuex'
    },
  },
  // 模块化部分,暂时忽略,后期在讲
  getters, // 不会修改state的值,类似于计算属性对其包装
  modules
})

2. Vuex 中 state 的使用
// 直接获取并赋值
this.$store.state.count = 1
// 使用 mapState 函数
import { mapState } from 'vuex'
computed: {
  ...mapState(['count']),
},
// 直接使用 this 即可
console.log(this.count)
3.Vuex 中 mutations 的使用
// 直接使用 commit 调用 mutations 中定义的函数
this.$store.commit('add')
// 使用 mapMutations 辅助函数
import { mapMutations } from 'vuex'
methods:{
  ...mapMutations(['addX'),
  changeCount(){
    // 在方法中直接使用 this. 调用 mutations 中的方法即可
    // 可传参数,使用 commit 同样
    this.addX(10)  
  },
}
4 .Vuex 中 actions 的使用
// 直接使用 dispatch 调用 actions 中定义的函数
this.$store.dispatch('addAsync')
// 使用 mapActions 辅助函数
import { mapActions } from 'vuex'
methods:{
  ...mapActions(['addAsync']),
  PromiseChangeVal(){
    // 使用方法与 mapMutations 类似
    this.addMoreAsync(6)
  }
}

5 . Vuex 中 getters 的使用

// 直接使用
this.$store.getters.getterCount
// 使用 mapGetters 辅助函数
import { mapGetters } from 'vuex'
computed: {
  ...mapGetters(['getterCount'])
},
// 使用 this. 即可
this.getterCount
四、Vuex modules

因为我并不喜欢给 Vuex namespaced,有需要的可以自行百度

模块化重点,也更加简便

  • modules 导出不添加 namespaced ,使用更方便

  • 需要使用到的 state 通过 getters 包装后导出

1. 先看下 Store 文件夹结构
|----|store // vuex 目录

|-------- |modules // 所有模块都在此目录中定义

|-------- | --------- |index.js // 所有模块导出后都在此文件导入并导出

|-------- | --------- |todoList.js // 模块化文件

|-------- |getters.js // 计算属性文件

|-------- |index.js // vuex导出最终文件

我们从内往外一步步实现模块化

  1. 在 store 目录下新建 modules 目录
  2. 在 modules 目录下新建模块化文件,如 todoList.js
  3. 在 modules 目录下新建 index.js,把所有模块化 js 文件全部引入并导出
  4. 在 store 目录下新建 getters.js 文件,包装后导出所有需要用到的state属性
  5. 在 store 目录下的 index.js 引入 modules 目录下的index.js 和 getters.js

在这里插入图片描述

2. modules 中的 模块化 js 文件这样写

以 todoList.js 为例

// 引入 axios 是为了请求接口,如在实际项目中使用直接引入封装好的 api 即可
import axios from 'axios'

// state mutations actions getters 均使用 const 定义
const state = {
  list: [],
  inputVal: ''
}
const mutations = {
  // 设置 list 的值
  setList (state, data) {
    state.list = data
  },
  // 修改 inputVal 的值
  changeInputVal (state, val) {
    state.inputVal = val
  },
}

const actions = {
  getList (content) {
    // actions 异步方法,在此使用 axios 请求获取数据
    axios.get('/list.json').then(res => {
      // 数据获取成功后使用 commit 调用 mutations 的方法给 list 赋值
      content.commit('setList', res.data)
    })
  }
}
const getters = {
  // getters 的意义 就是如果在页面直接使用模块化中 state 的属性会报错 undefined
  getterCount (state) {
    // 计算属性,不在此导出的话也可以统一在 getters.js 文件中封装
    // 但是一定要把值 return 出去
    return state.list.filter(item => !item.done).length
  }
}
// 这里一定要导出
export default {
  state,
  mutations,
  actions,
  getters
}
3. modules 中的 index.js 这样写
import todoList from './todoList'
// 如果有多个模块,只需参考这种形式引入即可
export default {
  // 导出亦是如此
  todoList
}
4. store 下的 getters.js 这样写
// 如果在模块化中使用 getters 函数包装了就不需要在这里再写一遍
export default {
  inputVal: state => state.todoList.inputVal,
  list: state => state.todoList.list
}
5. store 下的 index.js 这样写
import Vue from 'vue'
import Vuex from 'vuex'
import modules from './modules' // 引入 modules 文件夹下的 index.js 也就是引入了全部的模块
import getters from './getters' // 引入 getters 计算属性文件

Vue.use(Vuex)
// 导出 new Vuex.Store 即可使用
export default new Vuex.Store({
  getters,
  modules
})
五、Vuex 持久化数据

为什么要持久化 Vuex

-------- 页面刷新会丢失 Vuex 中的值

Vuex 持久化方法

// 使用 vuex-persistedstate 插件
npm install vuex-persistedstate
// store 目录下 index.js 使用
import createPersistedState from 'vuex-persistedstate';
export default new Vuex.Store({
  getters,
  modules,
  // 在此配置
  plugins:[
    createPersistedState({
      // 默认存储在 localStorage 中
      // 也可配置成 sessionStorage cookie
      storage:window.sessionStorage // 注意
    })
  ],
})
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端大斗师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值