vue + vuex 的状态管理的简单使用

每一份总结总会有一份收获……

VUE + vuex 的状态管理的简单使用:

使用webpack开发VUE的组件中,每个组件的样式,js,数据,一般情况下都是独立的。但是有些时候,我们希望有些数据是共享的,比如组件A中点击事件操作某个标签的v-show=’flag’进行显示和隐藏,组件B中也需要操作该标签的显示个隐藏。在这种情况下,结合父组件可以实现同时操作,但是你会发现你的代码比较繁琐,当应用程序变得庞大时,也就很难管理和维护这些状态。

而VUEX则提供了统一集中的状态管理。

vuex的核心:
这里写图片描述

流程:组件事件>dispatch>Actions(数据获取,如从后台获取数据)>commit>Mutations(数据操作,改变状态)>state>render>组件视图

在actions获取数据,在mutations处理数据,,在getters提供数据,这样就很方便的管理了数据状态。

如何简单的使用vuex?

首先使用vue-cli手脚架初始化了一个demo
安装vue-cli:

npm install vue-cli -g

初始化demo,如果看不懂提示则一路按回车即可。

vue init webpack-simple demo    //使用的是简化版的webpack,完整版则是去掉-simple

当有提示有 :
cd demo
npm install
npm run dev
则初始化完成。

切换文件夹:

cd demo

安装node_modules:

npm install

运行项目:

npm run dev

最后的目录结构:

这里写图片描述

packege.json:

"dependencies": {
    "vue": "^2.3.3",
    "vuex": "^2.3.1"//需要自己安装:npm install vuex --save
  },
  "devDependencies": {
    "babel-core": "^6.0.0",
    "babel-loader": "^6.0.0""babel-preset-env": "^1.5.1",
    "cross-env": "^3.0.0",
    "css-loader": "^0.25.0",
    "file-loader": "^0.9.0",
    "node-sass": "^4.5.0",
    "sass-loader": "^5.0.1",
    "vue-loader": "^12.1.0",
    "vue-template-compiler": "^2.3.3",
    "webpack": "^2.6.1",
    "webpack-dev-server": "^2.4.5"
小例子:

在src文件夹创建vuex的store目录结构:

└── src
    ├── assets
    └── store
        ├── index.js          # 我们组装模块并导出 store 的地方
        ├── actions.js        # 根级别的 action
        ├── mutations.js      # 根级别的 mutation
        ├── getters.js        //提供数据
        ├── types.js          //类型
        └── modules           //分模块
            ├── cart.js       # 购物车模块
            └── products.js   # 产品模块
    ├── App.vue
    ├── main.js

从App.vue 开始缕。

1.首先我们希望是点击增加按钮时触发increment事件时count变更,在不实用VUEX之前是直接写在了methods里,这样其他地方也想操作count时,就需要写很长的代码,同时也不好管理。使用VUEX时,则提交给mapActions进行统一管理。
<template>
  <div id="app">
      <h3>welcome vuex-demo</h3>
      <input type="button" value="增加" @click="increment">
      <input type="button" value="减少" @click="decrement">
      <div>
        现在数字为: {{count}}, 它现在是 {{even}} //渲染
      </div>
  </div>
</template>

<script>
import {mapActions,mapGetters} from 'vuex'//导入vuex的mapActions,mapGetters方法
export default {
    computed:mapGetters([           //使用mapGetters获取改变后的数据
            'count',
            'even'
    ]),
    methods:mapActions([         //使用mapActions提交方法到了actions
         'increment',
         'decrement'
    ]),
}
</script>
2. actions收到数据后进一步处理,如果有请求后台数据时,在这里请求
actions.js:
import * as types from './types'//导入所有定义的类型, *代表导入所有,当然也可以不实用types,type的作用是当作参数传递
export default{
    increment:({ //从app.vue接收到的increment方法进一步处理
        commit //接收commit参数
    })=>{
        commit(types.INCREMENT);//进一步的提交到muations ,types.INCREMENT 是参数,等于INCREMENT 如果没有定义types,则传入increment,参数名称可以自定义,但建议最好使用types统一
    },
    decrement:({
        commit
    })=>{
        commit(types.DECREMENT);
    }
}

types.js:

export const INCREMENT = 'INCREMENT'//设置常量,用作参数传递
export const DECREMENT = 'DECREMENT'
3. actions 提交后commit后,接着是mutations进行处理

mutations.js:

import {
    INCREMENT,  //导入定义的types
    DECREMENT
} from './types'

import getters from './getters'   // 导入getters

const state = {//设置状态,在这里定义数组,布尔,对象
    count:20,
    //flag:false
}
const mutations = {//定义mutations
    [INCREMENT](state){ //[INCREMENT]是引用types变量,接收state参数,在这里更改和操作数据状态,
        state.count++;
        //flag:false;
    },
    [DECREMENT](state){
        state.count--;
    }
}
export default{//导出
    state,
    mutations,
    getters

}

gtters.js文件:

export default{
    count:(state)=>state.count,//接收state,并return state.count
    even:(state)=>state.count%2==0?'偶数':'奇数'
}
4. 在主文件中引用actions ,mutations

index.js:

import Vue from 'vue'
import Vuex from 'vuex'
import actions from './actions'//引入actions
import mutations from './mutations'//引入mutations

Vue.use(Vuex)//vue使用vuex

export default new Vuex.Store({//导出
    modules:{
        mutations
    },
    actions
})
5. 最后在main.js中注入:

main.js:

import Vue from 'vue'
import App from './App.vue'
import store from './store'//引入store的index.js

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

这样就完成了一个简单的vuex的小例子,使用了vuex后,我们只需要管理store 里的actions,mutations,getters,即可。

只有使用了,才能真正体会vuex的核心思想,个人觉得管理数据非常方便。

使用对象拓展运算符分发action

app.vue中的methods和comouted是被mapActions,mapGetters占用了,无法写组件自己独立的方法。有时我们还想使用组件自己的方法时,因为有些数据不共享,所以我们希望写在组件里就可以。那么则可使用使用对象拓展运算符来解决。

前面是这样写的,想增加方法时,无法增加,解决办法请往下看。

import {mapActions,mapGetters} from 'vuex'//导入vuex的方法
export default {
    computed:mapGetters([//获取数据
            'count',
            'even'
    ]),
    methods:mapActions([//提交方法到了actions
         'increment',
         'decrement'
    ]),
}

首先修改App.vue如下:

<script>
    import {mapActions,mapGetters} from 'vuex'
    export default {
        computed:{
            ...mapGetters([  //...是对象拓展元算符
                'count',
                'decre'
            ])
             b:{//这里写计算属性
                  get:()=>this.a+2,
                  set(val){
                      this.a=val;
                  }
            }
        },
        methods:{
            ...mapActions([
                'increment',
                'decrement'
            ]),
            fn(){
                console.log('这是组件的方法');
            }
        },
        mounted(){
            this.fn();//调用组件的方法
        }

    }
</script>

但你会发现…mapActions 和…mapGetters这方法无法使用,因为浏览器还没支持,所以会报错。解决办法请往下:

解决vuex的…mapGetters和…mapActions报错的方法

1.安装babel插件:

npm install babel-plugin-transform-object-rest-spread --save-dev
  1. 安装es2015插件,如果安装了babel-preset-env插件,就不用安装es2015了
npm install babel-preset-es2015 --save-dev

3 . 修改.babelrc文件:

{
  "presets": [
    ["env", { "modules": false }], //如果有了这个,就不用重新配置下面的es2015了
    ["es2015", { "modules": false }]
  ],
   "plugins": ["transform-object-rest-spread"]
}

这样就可以解决对象拓展运算符的报错。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值