vue进阶——vuex状态管理

vuex状态管理

vuex官网的介绍:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。可以把他认为是另外一个存放公共变量的地方,但是同时面临变量会被某个组件更改,从而使得其他组件内容也发生更改。所以维护状态的唯一性就变的格外重要,接下来就让我们来了解一下vuex

一、vuex安装

  1. npm安装:npm install vuex --save
  2. CDN引入:

二、vuex的注册和基本架构

// 引入vue与vuex
import Vue from 'vue'
import Vuex from 'vuex'

// 注册
Vue.use(Vuex)

// 引入子仓库
import son from './module/son'

// 导出
export default new Vuex.Store({
  // 仓库
  state: {
  },
  // 同步
  mutations: {},
  // 异步
  actions: {},
  // 子模块
  modules: {
    son
  },
  // 计算属性
  getters: {}
})

// 在main.js文件下

// 引入
import store from './store'

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

三、state单一状态树

Vuex 使用单一状态树——是的,用一个对象就包含了全部的应用层级状态。就是说state就是一个应用里面的数据源,而里面的数据都是响应式的,当数值发生改变时其他引用此状态时也会发生改变。需要注意的是vuex属于单向数据流不能直接更改state里面的数据,具体怎么更改后面会讲到;

  1. 在组件中如何获取vuex状态

// 方法一:在组件中导入store对象
import store from "@/store/index.js"
// 使用
this.list = store.state.list

// 方法二:store默认绑定在vue原型上可以直接访问
this.list = this.$store.state.list

// 方法三:使用计算属性返回状态
computed: {
	getList(){
		return this.$store.state.list;
	}
}

  1. 辅助函数mapState

    当一个组件需要多个计算属性时就会有大量代码重复,由此出现了辅助函数来解决这个问题;
// 使用计算属性映射出来,可以直接映射到当前组件this上
computed: mapState(['list']),
// 或者
computed: mapState({
	list: state=>state.list
}),

// 当想要modules里面的state话
computed: mapState({
	list: state=>state.son.list
}),
// 还可以使用对象展开运算符,把数据源解构出来
computed: {
	...mapState({
		list: state=>state.list,
		sonList: state=>state.son.sonSlist
	})
}

四、Getter计算属性

getter可以认为是 store 的计算属性,对 state 的加工,是派生出来的数据。就像 computed 计算属性一样,getter 返回的值会根据它的依赖被缓存起来,且只有当它的依赖值发生改变才会被重新计算,可以同时被多个组件共享;需要注意的是:getter属性可以改变state状态值

// 假设在store中有一个计算属性
const store = new Vuex.Store({
  state: {
    list: []
  },
  getters: {
    fun: (state,getters) => {
      return state.list.length
    }
  }
})

// 在组件中
// 方式一:store.getters.fn,$store.getters.fn
// 方式二:使用mapGetters辅助方法映射出来
 computed: {
  // 使用对象展开运算符将 getter 混入 computed 对象中
    ...mapGetters(['fun'])
  }
// 子仓库中的计算属性
...mapGetters('仓库名',['方法名'])

五、mutations同步改变state状态值

Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数。使用的时候用commit()来触发;注意:mutations中只能存放同步方法,无法调用异步方法

// 假设在store中有一个同步函数
const store = new Vuex.Store({
  state: {
    list: []
  },
  mutations: {
    fun: (state,params) => {
      state.list = params;
    }
  }
})

// 在组件中
// 方式一:store.commit('fun', 10),$store.commit('fun', 10)
// 方式二:使用mapMutations辅助方法映射出来
 computed: {
  // 使用对象展开运算符将 mutations混入 methods对象中
    ...mapMutations(['fun'])
  }
// 子仓库中的计算属性
...mapMutations('仓库名',['方法名'])

六、actions异步方法

为了解决mutations无法调用异步回调,便是使用Action来发起异步方法, Action提交的是 mutation,而不是直接变更状态。Action 可以包含任意异步操作。Action 通过 store.dispatch 方法触发,返回的是Promise对象;注意:在不同模块中可以触发多个 action 函数。在这种情况下,只有当所有触发函数完成后,返回的 Promise 才会执行。

// 假设在store中有一个异步函数
const store = new Vuex.Store({
  state: {
    list: []
  },
  mutations: {
    fun: (state,params) => {
      state.list = params;
    }
  },
  actions: {
	api: (context) {
		context.commit('fun');
    }
  }
})

// 在组件中
// 方式一:store.dispatch('api'),$store.dispatch('api')
// 方式二:使用mapActions辅助方法映射出来
 computed: {
  // 使用对象展开运算符将 Actions混入 methods对象中
    ...mapActions(['api'])
  }
// 子仓库中的计算属性
...mapActions('仓库名',['方法名'])

六、module子模块仓库

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割。注意:子模块创建时必须先创建独立命名空间namespaced: true;这样模块才能相对独立,具有更高的封装度和复用性

你可能感兴趣的:(vue,vue)