vuex及其五大核心功能运用解析

什么是vuex?

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

什么情况下使用vuex?

如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

vuex流程?

vuex引用?

1.如果项目安装时没有集成vuex,那么首先安装vuex:

npm install vuex --save

2.在main.js中注入:

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

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

 

state在项目中的运用?

store目录下的index.js

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

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    peopleList:[
      {name:'zql',age:20},
      {name:'lyh',age:22},
      {name:'zjk',age:25},
    ]
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  }
})

HelloWorld.vue组件中

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <div v-for="(item,index) in peopleList" :key="index">
      <p>姓名:{{item.name}},年龄:{{item.age}}</p>
    </div>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data () {
    return {
      peopleList: this.$store.state.peopleList
    }
  }
}
</script>

============================================================================================

效果:

=============================================================================================

statevuex的唯一数据源,是所有组件的公共data

在组件中,使用this.$store.state.peopleList获取state中的数据。

如果需要获取多个state,可使用...mapState辅助函数:

 

store目录下的index.js

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

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    peopleList:[
      {name:'zql',age:20},
      {name:'lyh',age:22},
      {name:'zjk',age:25},
    ],
    desList:[
      {des:'一杆梅子酒'},
      {des:'逍遥抖机括'},
      {des:'烈酒送入喉'},
    ]
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  }
})

HelloWorld.vue组件中

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <div v-for="(item,index) in peopleList" :key="index">
      <p>姓名:{{item.name}},年龄:{{item.age}}</p>
      <p>{{desList[index].des}}</p>
    </div>
  </div>
</template>

<script>
import {mapState} from 'vuex'
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data () {
    return {
      // peopleList: this.$store.state.peopleList
    }
  },
  computed: {
    ...mapState(['peopleList','desList'])
  }
}
</script>

====================================================================

效果:

====================================================================

getters项目中的运用?

store目录下的index.js
  getters: {
    computedPeopleList: (state) => {
      let newName = state.peopleList.map((item)=>{
        return {
          name: '*' + item.name + '*',
          age: item.age
        }
      })
      return newName;
    }
  },

HelloWorld.vue组件中

  data () {
    return {
      // peopleList: this.$store.state.peopleList,
      peopleList: this.$store.getters.computedPeopleList
    }
  },
getters用于从state中派生出一些状态,例如对列表进行过滤等。可以将getters理解为计算属性computedgetter的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
 
getters接受state作为其第一个参数。
 
这时我们可以在store.js中添加一个getter属性:computedPeopleList,用于修改显示名字。
 
在组件中,使用this.$store.getters.computedPeopleList获取getters中的数据。
 
=======================================================================================
效果:
=======================================================================================
 
同state,如果需要使用多个getters,可使用...mapGetters辅助函数
import {mapState,mapGetters} from 'vuex'


computed: {
    ...mapState(['desList']),
    ...mapGetters(['computedPeopleList'])
}

mutations在项目中的运用?

更改vuexstore中的状态的唯一方法是提交mutation
 
vuex中的mutation类似于事件:每个mutation都有一个字符串的事件类型和一个回调函数
 
这个回调函数就是我们实际进行状态更改的地方,并且它会接受state作为第一个参数(payload为第二个参数,也就是自定义参数)。

此时,我们给store添加个mutation属性,用于点击按钮时修改描述:

store目录下的index.js

  mutations: {
    updateDesList: (state,payload) => {
      return state.desList.forEach((item) => {
        item.des = payload + '何妨千金與落魄'
      })
    }
  },

HelloWorld.vue组件中

  methods: {
    changeDes(){
      this.$store.commit('updateDesList','肝膽催月落,')
    }
  }

==========================================================================

点击按钮效果:

==========================================================================

同样,可通过mapMutations映射mutations

store目录下的index.js

  state: {
    peopleList:[
      {name:'zql',age:20},
      {name:'lyh',age:22},
      {name:'zjk',age:25},
    ],
    desList:[
      {des:'一杆梅子酒'},
      {des:'逍遥抖机括'},
      {des:'烈酒送入喉'},
    ],
    listName: '四爺'
  },
  mutations: {
    updateDesList: (state,payload) => {
      return state.desList.forEach((item) => {
        item.des = payload + '何妨千金與落魄'
      })
    },
    reUpdate: (state,status) => {
      state.listName = status;
    }
  },

HelloWorld.vue组件中

import {mapState,mapGetters,mapMutations} from 'vuex'

  methods: {
    changeDes(){
      this.$store.commit('updateDesList','肝膽催月落,')
    },
    ...mapMutations(['reUpdate']), //將this.$store.commit() 映射为 this.reUpdate()
    updateName(){
      this.reUpdate('牧馬城市')  //等同于this.$store.commit('reUpdate','牧馬城市')
    }
  }


<h2 @click="updateName">{{ listName }}</h2>

action在项目中的运用?

action类似于mutation,不同之处在于:

1.action提交的是mutation,而不是直接变更状态。

2.action可以包含异步操作,而mutation不行。

3.actions中的回调函数的第一个参数是context, 是一个与store实例具有相同属性和方法的对象。

4.action通过store.dispatch方法触发,mutation通过store.commit方法提交。

store目录下的index.js

  actions: {
    saveListName({commit},status){
      commit('reUpdate',status)
    }
  },

HelloWorld.vue组件中

    reUpdateName(){
      let self = this;
      self.$store.dispatch('saveListName','灵魂不再无处安放')
    }

同样,可通过mapActions映射actions,类似mapMutations:

import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'


  methods: {
    changeDes(){
      this.$store.commit('updateDesList','肝膽催月落,')
    },
    ...mapMutations(['reUpdate']), //將this.$store.commit() 映射为 this.reUpdate()
    updateName(){
      this.reUpdate('牧馬城市')  //等同于this.$store.commit('reUpdate','牧馬城市')
    },
    ...mapActions(['saveListName']),
    reUpdateName(){
      let self = this;
      // self.$store.dispatch('saveListName','灵魂不再无处安放')
      self.saveListName('灵魂不再无处安放')
    }
  }

actions中的异步现象:

store目录下的index.js

  actions: {
    saveListName({commit},status){
      commit('reUpdate',status)
    },
    changeListName(context,status){
      setTimeout(()=>{
        context.commit('reUpdate',status)
      },2000)
    }
  },

HelloWorld.vue组件中

  methods: {
    reUpdateName(){
      this.$store.dispatch('changeListName','夜泊寄宿酒家')
    }
  }

modules在项目中的运用?

如果一个项目非常大的话状态就会非常的多,如果不进行分类处理,所有的状态都维护在一个state里面的话,状态管理就会变得非常的混乱,这样非常不利于项目的后期维护,所以store有了我们的modules:

一个简单的模块化目录:

在store.js中:

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

import login from './modules/login'

Vue.use(Vuex);
export default new Vuex.Store({
    modules: {
        login
    },
    state:{ //右侧收缩框状态
        changShow: 0
    },
    getters:{
        isShow(state){
            return state.changShow
        }
    },
    mutations:{
        show(state){
            state.changShow = 1;
        }
    }
})

在login.js中:

const state = {
    userInfo: localStorage.userInfo ? localStorage.userInfo : {}
}

const mutations = {
    userInfo(state, _userInfo) {
        state.userInfo = _userInfo;
    }
}

const getters = {
    getUserInfo(state) {
        return typeof state.userInfo == "string" ? JSON.parse(state.userInfo) : state.userInfo
    }
}

const actions = {
    saveUserInfo({ commit }, _userInfo) {
        localStorage.userInfo = JSON.stringify(_userInfo)
        commit('userInfo', _userInfo);
    }
}

export default {
    state, mutations, actions, getters
}
posted on 2020-01-03 18:04  活在当下zql  阅读(1354)  评论(0编辑  收藏  举报