Vuex知识点总结

Vuex是什么

介绍:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
采用集中式存储管理应用中的所有组件的状态,适用于中大型项目的的开发

为什么使用vuex

由于Vue是单向数据流,组件之间的通讯都是依靠子传父,父传子,或者建立一个空的vue实例从而进行兄弟之间的传参,随着中大型项目的开发,组件越来越多,传统的传参模式显得太过于繁琐,于是vuex为此而来

Vuex的工作流程

官方给了一张超级完美的流程图。↓
详细简洁易懂
vuex最繁琐的工作流程通过此图分析也显得非常易懂。列如:
组件想要修改state,通过this. s t o r e . d i s p a t c h ( " a c t i o n s 中 的 方 法 名 " ) 调 用 a c t i o n s 中 的 方 法 , 在 a c t i o n s 中 通 过 t h i s . store.dispatch("actions中的方法名")调用actions中的方法,在actions中通过this. store.dispatch("actions")actionsactionsthis.store.commit(“mutations中的方法名”)调用mutations中的方法,在mutations中修改state中的数据,state中的数据发生改变就会立即响应到组件上

vuex使用之前的配置

  • 安装vueX↓
cnpm install vuex -S

注:
-S 是–save的简写,意为:把插件安装到dependencies(生产环境依赖)中
-D是–save-dev的简写,意为:把插件安装到devDependencies(开发环境依赖)中

  • 完整的vuex代码片段↓(在src中创建store文件夹,并在其内创建index.js)↓
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
    
    
  state: {
    
    
  },
  mutations: {
    
    
  },
  actions: {
    
    
  },
  modules: {
    
    
  }
})
  • 在main.js(vue项目的入口文件)中进行引入,并放到vue的实例中↓
import store from './store' //index.js可无需写入,vue会自动读取文件夹内的index.js文件
new Vue({
    
    
  router,
  store,
  render: h => h(App)
}).$mount('#app')

vuex的核心概念

vue官方给出的是每一个 Vuex 应用的核心就是 store(仓库)。
但是在store中衍发出来了五大核心概念,即state、mutations、actions、getters、modules。

state(单一状态树—状态)

state是vueX存放数据的地方
Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。因此我们通常把state中的数据放到computed(计算属性)中,然后返回

  • 在state中定义vueX中的数据↓
  state: {
    
    
    count:100,
    price:25
  }
  • 在计算属性中进行获取并返回
    每当 this.$store.state.count 变化的时候, 都会重新求取计算属性,并且触发更新相关联的 DOM↓
computed: {
    
    
    count () {
    
    
      return this.$store.state.count
    }
  }
  • 将计算属性中返回的数据放在template模板中↓
<p>{
   
   {count}}</p>

也可以通过这种方式进行渲染state(不推荐)↓

<p>{
   
   {$store.state.count}}</p>

这样我们就将vuex中的数据渲染到模板上了

mutations(状态更新—事件

mutations是唯一能操作state中数据的地方,mutations中默认的第一个参数是state,后面的数据都是我们需要传递的参数

  • 在组件中通过this.$store.commit('mutations中的事件名',参数)调用mutations中的方法↓
  plus(){
    
    
    this.$store.commit("ADD",2)
  }
  • 最终在mutations中进行操作↓
mutations: {
    
    
  ADD(state,val){
    
    
    state.count+=val
  }
}

actions(异步)

作用:是用来代替Mutation进行异步操作的

  • 在组件中通过this.$store.dispatch("actions中的方法名",参数)来调用actions中的方法↓
plus(){
    
    
this.$store.dispatch("GOADD",5)
}
  • 在actions中调用mutations中的方法(actions中默认的第一个参数指向store(这个参数有两种代替方式1.context 2.{commit}),其后皆是我们需要传递的形参)
  • 方案一 ↓
GOADD(store,val){
    
    
  store.commit("ADD",val)
}
  • 方案二↓
GOADD(context,val){
    
    
  context.commit("ADD",val)
}
  • 方案三↓
GOADD({
    
    commit},val){
    
    
  commit("ADD",val)
}
  • 在mutations中进行更改state数据
ADD(state,val){
    
    
  state.count+=val
}

getters(计算)

该方法类似于computed(计算属性),可以将state中的数据做进一步的处理

  • 在getters中将state中的进行计算↓
sum(state){
    
    
  return state.count * state.price
}
  • 在computed中将getters进行返回↓
 sum(){
    
    
   return this.$store.getters.sum
 }
  • 在模板中进行渲染↓
<p>{
   
   {sum}}</p>

此方式依旧不推荐↓

<p>{
   
   {$store.getters.sum}}</p>

modules(模块)

使用前提:当我们的项目在vuex中使用了过多的数据,从而会导致代码体积太过于庞大,不利于维护
Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter。

  • 创建modules模块↓
const modulesA={
    
    
  state:{
    
    
  	count:1000
  },
  actions:{
    
    },
  getters:{
    
    },
  mutations:{
    
    
	ADD(state){
    
    
	state.count++
	}
  }
}
const modulesB={
    
    
  state:{
    
    },
  actions:{
    
    },
  getters:{
    
    },
  mutations:{
    
    }
}
export default new Vuex.Store({
    
    
  modules: {
    
    
    MA:modulesA,
    MB:modulesB
  }
})
  • 在组件中进行调用mudules模块中的state数据,依旧在computed中对数据进行一波返回,以及调用MA模块中的mutations中的方法↓
//computed计算属性中   
 number(){
    
    
   return this.$store.state.MA.count  //获取MA模块中state里面的count数据
 }
 //methods方法模块中     
 add(){
    
    
 this.$store.commit("ADD")   //调用MA模块中mutations里面的ADD方法
 }

总结:this.$store.state.'模块名'.'此模块state中的数据名',MA模块中的getters:“俺也一样”
this.$store.commit("模块中mutations中的方法名")MA模块中的actions:“俺也一样”

ES6模块化

此方法,个人觉得更利于维护和开发,更能大幅度降低单个js(store文件夹下面的index.js)文件的代码量,使代码看起来不是那么的臃肿。

  • 方法如下↓
    在store文件夹内创建state.js、mutations.js、getters.js、actions.js文件,在index.js文件中进行引入
    列:state.js中的内容,其他js文件:“俺也一样”↓
const state={
    
    
  count:1000
}
export default state

列:index.js↓

import Vue from 'vue'
import Vuex from 'vuex'
import state from "./state"
import mutations form "./mutations"
import actions form "./actions"
import getters form "./getters"
Vue.use(Vuex)
export default new Vuex.Store({
    
    
  state,
  mutations,
  actions,
  getters,
  modules:{
    
    
    //TODO
  }
})

上方state是state:state的简写,es6规定属性名和属性值名字相同,可简写为单个名字
文件虽然多了,但是单个js文件的代码量少了,如果你们觉得可还行,可以参考哦^ (#^ . ^#) ^
当然也可以结合vueX中的modules一起使用
且看以下代码,亲测有效(在store文件夹内创建一个modulesA.js,并导出)↓
index.js代码↓

import Vue from 'vue'
import Vuex from 'vuex'
import ModulesA from "./modulesA"
Vue.use(Vuex)
export default new Vuex.Store({
    
    
  modules:{
    
    
    MA:ModulesA
  }
})

modulesA.js代码↓

import state from "./state"
const modulesA={
    
    
state
}
export default modulesA**

state.js代码↓

const state={
    
    
  count:1000
}
export default state

到此vueX的内置核心都已说完了,接下来上甜品↓看下方标题

vueX中的辅助函数

vueX中的语法糖mapState,mapActions,mapMutations,mapGetters
当一个组件需要多个状态时,这些状态都声明成计算属性过于冗长。于是有了辅助函数。

<template>
  <div class="home">
    <p>{
    
    {
    
    num}}</p>
    <button @click="ADD">加一</button>
  </div>
</template>

<script>
//导入vueX中mapState、mapMutations、mapGetters、mapActions的语法糖
import {
    
    mapState,mapMutations,mapGetters,mapActions} from "vuex"
export default {
    
    
  name: 'Home',
  computed:{
    
    
    ...mapState({
    
    num:'count'}),//也可以写成数组的形式,num是自定义名字,如若不自定义,可以写成数组的形式,参考mapMutations。
    ...mapGetters()
  },
  methods:{
    
    
    ...mapMutations(["ADD"]),//在模板的按钮中可以直接调用mutations中的方法。
    ...mapActions()
  }
}
</script>

辅助函数结合模块一起使用

  • 在模块中要开启命名空间
let moduleA = {
    
    
  namespaced: true, //开启命名空间。
  state: {
    
    },
  actions: {
    
    },
  mutations: {
    
    },
  getters: {
    
    }
}
const store = new Vuex.Store({
    
    
  modules: {
    
    
  	moduleA
  },
  • 在组件中引入vuex中的createNamespacedHelpers(命名空间辅助函数),拿到此函数内引入的模块名字,然后就可以愉快的使用了。在里面也可以进行重命名哦。

列如:当我们在此组件用到了vuex中公共的数据,同时也用到了模块中的数据,我们就可以用重新命名解决

<template>
  <div id="app">
    {
    
    {
    
    count}}
      <button @click="add">点击</button>
  </div>
</template>
<script>
import {
    
    createNamespacedHelpers} from 'vuex'   //引入命名空间辅助函数
const {
    
    mapState:mapStateModuleA,mapActions:mapActionModuleA,mapMutations:mapMutationModuleA,mapGetters:mapGetterModuleA} = createNamespacedHelpers('moduleA')
export default {
    
    
  methods:{
    
    
    ...mapActionModuleA(),
    ...mapMutationModuleA({
    
    add:'ADD'})
  },
  computed:{
    
    
    ...mapStateModuleA(['count']),
    ...mapGetterModuleA()
  }
}
</script>

呼!简单很多了吧,vuex这几个语法糖确实惊艳到我了,真的少了很多代码量。nice!

vueX数据持久化

有时候我们刷新页面,vuex的数据会变成初始化时候的数据,所以我们就需要保存vuex中的state里面的数据的状态,从而刷新页面,数据依然在。

  • 安装vuex-persistedstate插件
npm install vuex-persistedstate -S
  • 进行如下配置
import createPersistedState from 'vuex-persistedstate'
const store = new Vuex.Store({
    
    
  state,
  mutations,
  actions,
  getters,
  plugins: [createPersistedState({
    
    
    storage: sessionStorage,
    key: "token"
  })]//会自动保存创建的状态。刷新还在
})

storage:存储方式。(sessionStorage,localStarage) key:定义本地存储中的key

猜你喜欢

转载自blog.csdn.net/shiqina/article/details/114253995
今日推荐