vuex 入门
1. 简介
vuex 是一个专为 vue.js 应用程序开发的状态管理模式. 它采用集中式存储管理应用的所有组件状态, 并以相应的规则保证状态以一种可测的方式发生变化.
简单来说, 用来集中管理数据, 类似与 React 中的 Redux, 都是基于 Flux 的前端状态管理框架
2. 基本用法
初始化项目 vuex-demo
vue init webpack-simple vuex-demo
2.1 安装 vuex
npm install vuex -S
2.2 创建 store.js 文件, 在 main.js 中导入并配置 store 选项
- main.js
- import Vue from 'vue'
- import App from './App.vue'
- import store from './store.js'
- new Vue({
- store, // 配置 store 选项, 指定为 store 对象, vue 会自动把 store 对象建到所有子组件中, 在子组件中通过 this.$store 访问该 store 对象
- el: '#app',
- render: h => h(App)
- })
2.3 编辑 store.js 文件
Vuex 的核心是 store(仓库), 相当于一个容器, 一个 store 实例中包含以下属性的方法:
state 定义属性(状态, 数据)
getters 用来获取属性
actions 定义方法(动作)
commit 提交变化, 修改数据的唯一方式就是显式的提交 mutations
mutations 定义变化
注意: 不能直接在 actions 中直接修改数据, 数据修改必须在 mutations
- store.js
- /*
- vuex 配置
- */
- import Vue from 'vue'
- import Vuex from 'vuex'
- Vue.use(Vuex);
- // 定义属性(数据)
- var state = {
- count:6
- }
- // 定义 getters
- var getters = {
- count(state){
- return state.count;
- },
- evenOrodd(state){
- return state.count%2==0?'偶数':'奇数';
- }
- }
- // 定义 actions, 要执行的操作, 如流程判断, 异步请求
- const actions = {
- increment(context){ // 参数 context 本身也是一个对象: 包含 commit,dispatch,state
- // console.log(context);
- context.commit('increment'); // 提交一个名为 increment 的变化, 名称可以自定义, 可以认为是类型名
- },
- //es6 写法
- /*
- increment({commit,state}){
- commit('increment'); // 提交一个名为 increment 的变化, 名称可以自定义, 可以认为是类型名
- },
- */
- decrement(context){
- if(context.state.count> 10){
- context.commit('decrement');
- }
- },
- incrementAsync({commit,state}){
- //es6 写法
- /*
- var p = new Promise((resolve,reject) => {
- setTimeout(() => {
- resolve();
- },3000);
- });
- p.then(() => {
- commit('incrementAsync');
- }).catch(() => {
- console.log('异步失败');
- });
- */
- new Promise(function(resolve,reject){
- setTimeout(function(){
- resolve();
- },3000);
- }).then(function(){
- commit('increment');
- }).catch(function(){
- console.log('异步失败');
- });
- }
- }
- // 定义 mutations, 处理状态 (数据) 的改变
- const mutations = {
- increment(state){
- state.count++;
- },
- decrement(state){
- state.count--;
- }
- }
- // 创建 store 对象
- const store = new Vuex.Store({
- state,
- getters,
- actions,
- mutations
- })
- // 导出 store 对象
- export default store;
2.4 编辑 App.vue 访问
在子组件中访问 store 对象的俩种方式:
+ 方式 1: 通过 this.$store 访问
+ 方式 2: 通过 mapState,mapGetters,mapActions 访问, vue 提供了俩个方法
mapGetters 获取属性(数据)
mapActions 获取方法(动作)
- App.vue
- <script>
- import {mapState,mapGetters,mapActions} from 'vuex'
- export default {
- name: 'app',
- data() {
- return {
- msg: 'Welcome to Your Vue.js App'
- }
- },
- // 方式 1: 通过 this.$store 访问
- /*
- computed:{
- count(){
- return this.$store.state.count;
- }
- }
- */
- // 方式 2
- /*
- computed:mapState([
- 'count'
- ]),
- */
- // 方式 3: 通过 mapGetters,mapActions 访问
- computed:mapGetters([
- 'count',
- 'evenOrodd'
- ]),
- methods:mapActions([
- 'increment',
- 'decrement',
- 'incrementAsync'
- ])
- }
- </script>
3. 更好的组织 vuex 项目结构
- |-src
- |-store
|-index.js // 我们组装模块并导出 store 的地方
|-getters.js // 根级别的 getter
|-actions.js // 根级别的 action
|-mutations.js // 根级别的 mutation
|-mutationtypes.js // 定义 mutation
|-modules // 分为多个模块, 每个模块都有自己的 state,getters,actions,mutations
|-user.js // 用户模块
|-cart.js // 购物车模块
|-goods.js / 产品模块
- |.....
- index.js
- import Vue from 'vue'
- import Vuex from 'vuex'
- Vue.use(Vuex);
- import getters from './getters.js'
- import actions from './actions.js'
- import user from './modules/user.js'
- export default new Vuex.Store({
- getters,
- actions,
- modules:{
- user
- }
- });
getters.js
- const getters = {
- evenOrodd(state){
- return state.user.count%2==0?'偶数':'奇数';
- }
- }
- export default getters;
actions.js
- import mutationtypes from './mutationtypes.js'
- const actions = {
- incrementAsync({ commit, state }) {
- new Promise((resolve, reject) => {
- setTimeout(() => {
- resolve();
- }, 3000);
- }).then(() => {
- commit(mutationtypes.INCREMENT)
- }).catch(() => {
- console.log('异步操作失败');
- });
- }
- }
- export default actions;
mutationtypes.js
- /*
- 定义类型常量
- */
- const INCREMENT = 'INCREMENT'
- const DECREMENT = 'DECREMENT'
- export default {
- INCREMENT,
- DECREMENT
- }
- user.js
- /*
- 用户数据
- */
- import mutationtypes from '../mutationtypes.js' // 一般把 mutation 行为定义成常量的形式, 一起放在 mutationtypes.js 中
- const state = {
- count:12
- }
- var getters = {
- count(state){
- return state.count;
- }
- }
- const actions = {
- increment({commit,state}){
- // commit('increment'); // 一般把 mutation 行为定义成常量的形式, 一起放在 mutationtypes.js 中
- commit(mutationtypes.INCREMENT);
- },
- decrement({commit,state}){
- if(state.count> 10){
- // commit('decrement');
- commit(mutationtypes.DECREMENT);
- }
- }
- }
- const mutations = {
- // increment(state){
- // mutationtypes.DECREMENT(state){ //mutationtypes.DECREMENT 是变量
- [mutationtypes.INCREMENT](state){ //ES6 中 [] 将变量转化为字符串
- state.count++;
- },
- [mutationtypes.DECREMENT](state){
- state.count--;
- }
- }
- export default {
- state,
- getters,
- actions,
- mutations
- }
- main.js
- import Vue from 'vue'
- import App from './App.vue'
- import store from './store/index.js'
- new Vue({
- store,
- el: '#app',
- render: h => h(App)
- })
- App.vue
- <script>
- import {mapState,mapGetters,mapActions} from 'vuex'
- export default {
- name: 'app',
- data() {
- return {
- msg: 'Welcome to Your Vue.js App'
- }
- },
- // 方式 1: 通过 this.$store 访问
- /*
- computed:{
- count(){
- return this.$store.state.count;
- }
- }
- */
- // 方式 2
- /*
- computed:mapState([
- 'count'
- ]),
- */
- // 方式 3: 通过 mapGetters,mapActions 访问
- computed:mapGetters([
- 'count',
- 'evenOrodd'
- ]),
- methods:mapActions([
- 'increment',
- 'decrement',
- 'incrementAsync'
- ])
- }
- </script>
来源: https://www.2cto.com/kf/201804/737756.html