vueX

Posted 知青先生

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vueX相关的知识,希望对你有一定的参考价值。

什么是vueX?

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

如何引用?

准备工作

js引入方式
<script src="/path/to/vue.js"></script>
<script src="/path/to/vuex.js"></script>
npm引入方式
npm install vuex --save
模块化的打包系统中
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

1、创建index.js文件

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

Vue.use(Vuex);
导入对应的组件状态管理文件
import State from './state';
统一在vuex的store对象中管理
const store = new Vuex.Store(State);
导出
export default store;

2、创建state.js文件

export default {
	state: {
		test: 0,
	
	},
	mutations:{ 
		'test': function(state, value) {
			state.test = value;
		}
	},
	getters:{
		'test': function(state) {
			return state.test;
		}
	}
};

--提交值
this.$store.commit('key',更新的内容);
--获取值 用变量进行接受
this.$store.getters.key  

3、引入项目中

在vue入口中引入store文件
import store from './store';
根组件注入store 的机制
new Vue({
  el: '#app',
  store: store,
});

state 单一状态树 当前状态

单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。
Vuex 的状态存储是响应式的,从 store 实例中读取状态最简单的方法就是在计算属性 (opens new window)中返回某个状态:

// 创建一个 Counter 组件
const Counter = {
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
      return store.state.count
    }
  }
}
在store.js中:
state: {
		test: 0,
	},

每当 store.state.count 变化的时候, 都会重新求取计算属性,并且触发更新相关联的 DOM。
Vue.use(Vuex):通过调用此vuex 外,在根组件中引入store,可以注入到每一个子组件中。子组件就能实时得到相应的数据

mapState:组件需要获取多个状态,生成计算属性,函数返回的是一个对象。
computed:监控自己定义的百年来那个,改变量不在data中定义,直接在computed中定义,最好的场景就是页面动态显示的结果,可以放到此处进行计算监控和显示

computed: {
  localComputed () { /* ... */ },
  // 使用对象展开运算符将此对象混入到外部对象中
  ...mapState({
    // ...
  })
}

Getter 获取状态

就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算

getters: {
    test:function(state){
	  return state.test;
	}
  }

this.$store.getters.test;

Mutation 提交状态

这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:

提交载荷(Payload)

可以向 store.commit 传入额外的参数,即 mutation 的 载荷(payload)

使用常量替代 Mutation 事件类型

使用文件单独放置常量,来进行系统引用
export const SOME_MUTATION = ‘SOME_MUTATION’

Mutation 必须是同步函数

mutations:{
		'test': function(state, value) {
			state.test = value;
		}
	}
	this.$store.commit('test',内容);
	

Action

Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作。

Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation

actions: {
  increment ({ commit }) {
    commit('test')
  }
}

分发 Action

Action 通过 store.dispatch 方法触发

store.dispatch('increment')

Actions 支持同样的载荷方式和对象方式进行分发:

// 以载荷形式分发
store.dispatch('test', {
  amount: 10
})

// 以对象形式分发
store.dispatch({
  type: 'test',
  amount: 10
})

在组件中分发 Action

import { mapActions } from 'vuex'

export default {
  // ...
  methods: {
    ...mapActions([
      'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`

      // `mapActions` 也支持载荷:
      'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
    ]),
    ...mapActions({
      add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
    })
  }
}

组合 Action

actions: {
  async actionA ({ commit }) {
    commit('gotData', await getData())
  },
  async actionB ({ dispatch, commit }) {
    await dispatch('actionA') // 等待 actionA 完成
    commit('gotOtherData', await getOtherData())
  }
}

Module模块

为了解决store 对象变得相当臃肿问题,vuex允许我们将store分割成模块,每个模块都有自己的state、mutation、action、getter、子嵌套模块

const moduleA = {
  state: () => ({ ... }),
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: () => ({ ... }),
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态

命名空间

加入namespaced: true 开启命名空间

const store = new Vuex.Store({
  modules: {
    account: {
      namespaced: true,

      // 模块内容(module assets)
      state: () => ({ ... }), // 模块内的状态已经是嵌套的了,使用 `namespaced` 属性不会对其产生影响
      getters: {
        isAdmin () { ... } // -> getters['account/isAdmin']
      },
      actions: {
        login () { ... } // -> dispatch('account/login')
      },
      mutations: {
        login () { ... } // -> commit('account/login')
      },

      // 嵌套模块
      modules: {
        // 继承父模块的命名空间
        myPage: {
          state: () => ({ ... }),
          getters: {
            profile () { ... } // -> getters['account/profile']
          }
        },

        // 进一步嵌套命名空间
        posts: {
          namespaced: true,

          state: () => ({ ... }),
          getters: {
            popular () { ... } // -> getters['account/posts/popular']
          }
        }
      }
    }
  }
})

以下分为两种使用情况
在带命名空间的模块内访问全局内容(Global Assets)

此处不是太理解…后面视频学习

在带命名空间的模块注册全局 action

root: true, 开启当前模块action全局模式

{
  actions: {
    someOtherAction ({dispatch}) {
      dispatch('someAction')
    }
  },
  modules: {
    foo: {
      namespaced: true,

      actions: {
        someAction: {
          root: true,
          handler (namespacedContext, payload) { ... } // -> 'someAction'
        }
      }
    }
  }
}

调试日志加载、开启严格模式、

仅供开发环境使用

import createLogger from 'vuex/dist/logger'

日志:plugins: [createLogger()]
严格模式:strict: true

const store = new Vuex.Store(
{plugins: [createLogger()],State,strict: true});

测试mutation、测试 Action、测试 Getter

需要插件和专属配置支持、比较麻烦

热重载

需要支持 mutation 和模块,你需要使用 store.hotUpdate() 方法:

// store.js
import Vue from 'vue'
import Vuex from 'vuex'
import mutations from './mutations'
import moduleA from './modules/a'
Vue.use(Vuex)

const state = { ... }

const store = new Vuex.Store({
  state,
  mutations,
  modules: {
    a: moduleA
  }
})

if (module.hot) {
  // 使 action 和 mutation 成为可热重载模块
  module.hot.accept(['./mutations', './modules/a'], () => {
    // 获取更新后的模块
    // 因为 babel 6 的模块编译格式问题,这里需要加上 `.default`
    const newMutations = require('./mutations').default
    const newModuleA = require('./modules/a').default
    // 加载新模块
    store.hotUpdate({
      mutations: newMutations,
      modules: {
        a: newModuleA
      }
    })
  })
}

在此声明,以上内容部分列子来于官方文档

以上是关于vueX的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段13——Vue的状态大管家

项目集成 vue-router 和 vuex

手把手教你学vue-4(vuex)

Vue 教程(四十九)Vuex 核心概念和项目结构

Vue 教程(四十九)Vuex 核心概念和项目结构

Vue 教程(四十九)Vuex 核心概念和项目结构