1

vuex是配合vue一块儿使用的一个状态管理工具。
我通常使用它来保存一些全局的数据,例如用户登录信息,用户身份信息,总之一些在很多页面都会使用到的信息,都保存在vuex里面,用的时候就不需要再去请求接口了,直接去vuex里面拿就可以了。
先放官网地址

安装

npm install vuex --save

配置

我实在vue-cli环境中使用vuex的,所以这里就以这个环境作为项目文件结构来写配置了。
先在src/assets文件夹中新建一个vuex/store.js文件,建好之后在文件中写如下代码:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
    state: {
        name: 'xiaoming',
        count: 1
    }
})
export default store

在main.js中引入store.js:

import store from '@/assets/vuex/store';

在全局构造器中注册一下:(这里千万别忘了)

new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>',
  store: store   //在根实例下面注册store,相当于全局注册,可以全局调用
})

//题外话
//在vue-cli中,引入某些特定后缀的文件是不需要写全后缀的,就像上面这个store
//因为在config/webpack.base.conf.js文件中,有这样一段代码:
    resolve: {
        extensions: ['.js', '.vue', '.json'],  //这些后缀的文件可以不写,可以自己随意添加
        alias: {   //模块别名定义,方便后续直接引用别名,无须多写长长的地址
          'vue$': 'vue/dist/vue.esm.js',
          '@': resolve('src'),  //从src文件夹开始寻找文件
        }
    }

到这里,vuex已经在你的项目中安装好并且可以使用了。你只需要在vue的html的部分写上如下代码:

<div>{{$store.state.name}}</div>       //页面中会显示'xiaoming'

或者在构造器里面写:

console.log(this.$store.state.name);      //打印'xiaoming'

html代码书写取值的时候可以不加this,script代码中必须加this。

使用

1.state状态对象的访问(我把state理解成vue构造器中的data)

state里面存放一些数据,例如用户姓名、性别、身份证号等等。之前我的访问方式是:

 {{$store.state.name}}    

但是上面这种写法太长了,而且看起来不直观,查阅过文档之后我发现,访问state对象可以有以下三种写法:

//如果我想在页面中只写{{name}},可以这样写:

 1. computed: {
        name() {
            return this.$store.state.name;
        }
    }
    
 2. import {mapState} from 'vuex';
    computed: mapState({
        name: state => state.name    //es6箭头函数
    })
 
 3. import {mapState} from 'vuex';
    computed: mapState(['name']);    //这种写法最简单,推荐

2.访问mutations方法(我把mutations理解成vue构造器中的methods)

先在store.js中写上如下代码:

const store = new Vuex.Store({
    state: {
        name: 'xiaoming',
        count: 1
    },
    mutations: {
        add(state,num) {   //接收一个外部参数
            state.count += num;
        },
        reduce(state) {
            state.count --;
        }
    }
})

原先我调用add和reduce方法的时候,写法是:

<div>{{count}}</div>
<button @click="$store.commit('add',10)">点击加十</button>
<button @click="$store.commit('reduce')">点击减一</button>

但是这种调用方法的写法也太长,需要写上$store.commit这种东西,太啰嗦。
模仿访问state的方法,它也有另外一种便捷的写法:

import {mapState,mapMutations} from 'vuex';
methods: mapMutations(['add','reduce']),
//需要注意的是,state写在computed里面,而mutations写在methods里面,因为它是在@click之后的方法

现在你可以这样调用它:

<div>{{count}}</div>
<button @click="$store.commit('add',10)">点击加十</button>
<button @click="reduce">点击减一</button>

3.访问getters(我把getters理解成vue构造器中的computed)

getters就像一道门,每操作一次数据,都会经过一次它。

现在,在store.js中加入getters代码:

const store = new Vuex.Store({
    state: {
        name: 'xiaoming',
        count: 1
    },
    mutations: {
        add(state,num) {   //接收一个外部参数
            state.count += num;
        },
        reduce(state) {
            state.count --;
        }
    },
    getters: {
        add100(state) {
            return state.conut += 100;   //每操作一次count,它都会加上100
        },
        changename(state) {
            return state.name + 'c';     //每操作一次name,它都会拼接上一个c    
        }
    }
})

怎么调用它呢?模仿state的调用方法。
因为它们都是对数据进行操作,不涉及方法,所以getters也写在computed中。

import {mapState,mapMutations,mapGetters} from 'vuex';

//现在来看computed的代码要怎么写
//在写state的时候,我们把computed中的代码写成了这样:
//computed: mapState(['name']);
//那如果现在再加入mapGetters,就需要改变computed的样子,具体应该这样写:

computed: {
    ...mapState(['name','count']),   //es6扩展运算符,用map必须得用这个,否则会报错
    ...mapGetters(['add100','changename']),
    count2: function() {
        return this.$store.state.count;
    }
}

此时,每当你操作一次button按钮,无论是加法还是减法,它都会对count进行+100的操作。当然,此时的name是不会改变的,即使你引入了changename方法,但因为没有改变过name,所以就不会出发changename方法。

4.访问actions

actions与getters的用法相似,但是它是异步调用,写在methods里面。(说实话我是没看懂这个actions有啥用)

先来完善一下我们的store.js中的代码:

const store = new Vuex.Store({
    state: {
        name: 'xiaoming',
        count: 1
    },
    mutations: {
        add(state,num) {   //接收一个外部参数
            state.count += num;
        },
        reduce(state) {
            state.count --;
        }
    },
    getters: {
        add100(state) {
            return state.conut += 100;   //每操作一次count,它都会加上100
        },
        changename(state) {
            return state.name + 'c';     //每操作一次name,它都会拼接上一个c    
        }
    },
    actions: {
        add1(context) {                    //参数context即全局上下文对象,store
            context.commit('add',10);      //通过context调用add方法
            setTimeout(()=>{context.commit('reduce')},3000)
        },
        reduce1({commit}) {                //{commit}是另一种传参方式,一个封装好的commit
            commit('reduce');
        }
    }
})

写好actions方法了之后,就来调用它,调用方法跟mutations差不多:

methods: {
    ...mapMutations(['add','reduce']),
    ...mapActions(['add1','reduce1']),
    aa(i) {
        console.log(i)
    }
}

在html代码中使用:

<button @click="add1">做加法</button>
<button @click="reduce1">做减法</button>

reduce1方法调用了mutations中的reduce方法,每次点击减1;
add1调用了mutations中的add方法,每次点击加10,同时在3秒钟之后,会调用一次减法,减去1;
因为还有getters的设置,所以每次操作的时候还会再加100。

以上就是vuex的大致用法了,我平时只有state用的比较多。
我对vuex的理解很浅,如有不对的地方,请指正。


蒋个笑话吧
43 声望3 粉丝