一.vuex介绍
官方文档Vuex是一个专门为Vue.js应用程序开发的状态管理模式, 它采用集中式存储管理所有组件的公共状态, 并以相应的规则保证状态以一种可预测的方式发生变化.
上图中绿色虚线包裹起来的部分就是Vuex的核心, state
中保存的就是公共状态, 改变state
的唯一方式就是通过mutations
进行更改
为什么要使用Vuex?
vue 各个组件之间传值是比较困难的,所以我们可以使用vuex来保存我们需要管理的状态值,值一旦被修改,所有引用该值的地方就会自动更新
二. 开始使用Vuex
步骤 1: 在src目录下新建一个目录store,在该目录下新建一个index.js文件,我们用来创建并导出vuex实例。index.js:
import Vue from 'vue'
import Vuex from 'vuex'
import myinfo from './myinfo'
Vue.use(Vuex)
// 创建vuex实列
const store = new Vuex.Store({
})
export default store
2.在main.js 文件下引入,再在vue实例全局引入store对象;
import store from './store' new Vue({ el: '#app', router: router, store: store, components: { App }, template: '<App/>', })
1.回到 scr/store/index.js 文件,继续 vuex, 实现一个完整的基础实列,每个属性注意看注释。
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const state = { // 要设置的全局访问的state对象 name: 'Tom', age: 18 } const getters = { // 实时监听state值的变化(最新状态) myName(state) { // 方法名随意,主要是来承载变化的name的值 return state.name } } const mutations = { // 一个对象,里面可以放改变state的初始值的方法 updateAge(state, age) { // 参数除了state之外还可以再传额外的参数(变量或对象); state.age = age } } const actions = { // 是个对象变量,可以包含任意异步操作,这里面的方法是用来异步触发mutations里面的方法 sureAge(context, age) { // 自定义触发mutations里函数的方法,context与store 实例具有相同方法和属性 context.commit('updateAge', age) } } export default new Vuex.Store({ state, getters, mutations, actions })
3.组件里面使用: src/components/demo/demo.vue
<template> <div class="msg"> <span class="name">{{this.$store.state.name}}</span> <span class="age">{{GetAge}}</span> <span @click="fun1">年龄变为20</span> </div> </template> <script> export default{ computed: { GetAge() { return this.$store.state.age } }, methods: { fun1() { // this.$store.commit('updateAge', 20) // commit mutations
this.$store.dispatch('sureAge', 20) // dispatch actions 方法 } } } </script>
大概展示效果
三. 使用Vuex的moudels
1.vuex 的moudels用来做什么?
在Vuex中State使用是单一状态树结构,应该所有的状态都放在state里面,如果项目比较复杂,那state是一个很大的对象,store对象也将对变得非常大,难于管理。
module:可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
2.module 结构和导出
const moduleA = { state: { ... }, mutations: { ... }, actions: { ... }, getters: { ... } } const moduleB = { state: { ... }, mutations: { ... }, actions: { ... }, getters: { ... } } export default new Vuex.Store({ modules: { moduleA , moduleB } })
3.列子: 将上文 scr/store/index.js 文件中 数据拿出来,在当前文件夹新建demo.js,放到里面
demo.js : 需要在module中加一个命名空间namespaced: true属性,否则命名无法暴露出来
const state = { // 要设置的全局访问的state对象 name: 'Tom', age: 18 } const getters = { // 实时监听state值的变化(最新状态) myName(state) { // 方法名随意,主要是来承载变化的name的值 return state.name } } const mutations = { // 一个对象,里面可以放改变state的初始值的方法 updateAge(state, age) { // 参数除了state之外还可以再传额外的参数(变量或对象); state.age = age } } const actions = { // 是个对象变量,可以包含任意异步操作,这里面的方法是用来异步触发mutations里面的方法 sureAge(context, age) { // 自定义触发mutations里函数的方法,context与store 实例具有相同方法和属性 context.commit('updateAge', age) } } export default{ namespaced: true, state, getters, mutations, actions }
此时的src/store/index.js :
import Vue from 'vue' import Vuex from 'vuex' import demo from './demo' // 引入module Vue.use(Vuex) export default new Vuex.Store({ modules: { demo } })
4.使用: 加上demo命名空间
this.$store.state.demo.name
有了命名空间之后,辅助函数: mapState, mapGetters, mapActions 函数也都有了一个参数,用于限定命名空间,
第二个参数对象或数组中的属性,都映射到了当前命名空间中。
demo.vue :
<template> <div class="msg"> <span class="name">{{GetName}}</span> <span class="age">{{GetAge}}</span> <span @click="fun1">年龄为20</span> </div> </template> <script> import {mapState, mapGetters, mapActions} from 'vuex' export default{ created() { console.log(this.$store.state.demo.name) }, computed: { // ...mapState({ // 1.通过 this.$store.state 直接获取参数, 需要指定命名空间 ) // GetName: state => state.demo.name, // GetAge: state => state.demo.age // }), ...mapState('demo', { // 或者命名空间 // GetName: state => state.name }), ...mapGetters('demo', { // 2.通过getters获取参数 映射的方式 GetName: 'myName', GetAge: 'myAge' }) }, methods: { // 对象和数组中的sureAge 都是和demo中的参数一一对应。 ...mapActions('demo', [ // demo 是指modules文件夹下的demo 'sureAge' // demo.js文件中的actions里的方法 ]), fun1() { this.sureAge(20) } } } </script>
参考文档: 官方文档