【Vue】15 VueX

【什么是VueX?】

VueX是一个专门为Vue.js应用程序开发的状态管理模式,

采用集中式存储管理应用的所有组件状态,

以相应的规则保证按照一种可预测的方式发生改变。

即把多个组件的变量统一放到一个地方管理

 

在项目中安装Vuex

npm install vuex

新建store目录和一个index.js

并写入以下代码:

import Vue from 'vue';
import VueX from 'vuex';

Vue.use(VueX);

const store = new VueX.Store({
    state : {
        count : 0
    },
    mutations : {
        increment(state) {
            state.count++;
        },
        decrement(state) {
            state.count--;
        }
    }
});

export default store;

其次,我们要让所有的Vue组件,都能使用store,

就需要在main.js中引入,引入方式与router一样

import Vue from 'vue'
import App from './App.vue'
import router from "./router"; // ./router/index.js 因为是index.js,可以默认不写
import store from "./store";

Vue.config.productionTip = false

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

在任意一个Vue组件中插值引入:

<template>
    <div>
        <h2>样本的标题</h2>
        <p>样本的标签</p>
        <p>{{$store.state.count}}</p>
    </div>
</template>

<script>
    export default {
        name: "sample"
    }
</script>

<style scoped>

</style>

可以看到这里已经完全取出来了

然后再编写两个按钮和对应的事件:

<template>
    <div>
        <h2>样本的标题</h2>
        <p>样本的标签</p>
        <p> <button @click="decrease">减少</button> {{$store.state.count}}  <button @click="increase">增加</button> </p>
    </div>
</template>

<script>
    export default {
        name: "sample",
        methods : {
            decrease() {
                this.$store.commit("decrement");
            },
            increase() {
                this.$store.commit("increment");
            }
        }
    }
</script>

<style scoped>

</style>

查看效果:

然后再主页面也渲染这个变量:

可以发现,是一样的:

就是为了一些公共变量而存在的

 

【State】

Vuex提出使用单一状态树,(单一数据源),就是将一堆公共的数据放到一起去管理

state的意义类似Vue实例的data对象,所有的数据信息存放state中,但是访问不建议也像vue那样直接引用

【Gettter】

我们需要从state中获取一些经过改变后的数据,可以使用getter

store的index.js

import Vue from 'vue';
import VueX from 'vuex';

Vue.use(VueX);

const store = new VueX.Store({
    state : {
        count : 0,
        studentList : [
            { id : 1, name : "张三", age : 23, gender : true },
            { id : 2, name : "李四", age : 24, gender : true },
            { id : 3, name : "王五", age : 25, gender : true },
            { id : 4, name : "阿伟", age : 26, gender : true },
            { id : 5, name : "杰哥", age : 27, gender : true },
        ]
    },
    mutations : {
        increment(state) {
            state.count++;
        },
        decrement(state) {
            state.count--;
        }
    },
    getters : {
        getStudentByAge(state) {
            return state.studentList.filter(e => e.age > 24);
        }
    }
});

export default store;

在组件中可以通过this.$store.getters.xxx获取

<p> {{$store.getters.getStudentByAge}} </p>

效果:

 

【Mutations】

用于对state中的数据进行修改,或者是传值,类似vue实例的methods

调用mutations中的方法,需要这样:

this.$store.commit('方法名称',参数列表)

【Actions】

需要注意的是,我们不会在mutations进行异步操作:【使用规范】

但是在某些特定需求的情况下必须使用:比如ajax异步请求

这时候我们就可以使用actions处理:

作用就是为了代替mutations来完成这种功能

 

context参数,是和Store对象具有相同方法和属性的对象

即我们可以使用context.commit调用mutations

import Vue from 'vue';
import VueX from 'vuex';

Vue.use(VueX);

const store = new VueX.Store({
    state : {
        count : 0,
        studentList : [
            { id : 1, name : "张三", age : 23, gender : true },
            { id : 2, name : "李四", age : 24, gender : true },
            { id : 3, name : "王五", age : 25, gender : true },
            { id : 4, name : "阿伟", age : 26, gender : true },
            { id : 5, name : "杰哥", age : 27, gender : true },
        ]
    },
    mutations : {
        increment(state) {
            state.count++;
        },
        decrement(state) {
            state.count--;
        }
    },
    getters : {
        getStudentByAge(state) {
            return state.studentList.filter(e => e.age > 24);
        }
    },
    actions : {
        increa(context) {
            context.commit('increment');
        }
    }
});

export default store;

调用actions的方法需要使用dispatch分发

<template>
    <div>
        <h2>样本的标题</h2>
        <p>样本的标签</p>
        <p> <button @click="decrease">减少</button> {{$store.state.count}}  <button @click="increase">增加</button></p>
    </div>
</template>

<script>
    export default {
        name: "sample",
        methods : {
            decrease() {
                this.$store.commit("decrement");
            },
            increase() {
                // this.$store.commit("increment");
                this.$store.dispatch('increa');
            }
        }
    }
</script>

<style scoped>

</style>

其实对比发现,就是多一个action处理:

 

actions可用于异步操作,即可以使用Promise,

在异步操作中放入Promise,成功或者失败后,调用对应函数

import Vue from 'vue';
import VueX from 'vuex';

Vue.use(VueX);

const store = new VueX.Store({
    state : {
        count : 0,
        studentList : [
            { id : 1, name : "张三", age : 23, gender : true },
            { id : 2, name : "李四", age : 24, gender : true },
            { id : 3, name : "王五", age : 25, gender : true },
            { id : 4, name : "阿伟", age : 26, gender : true },
            { id : 5, name : "杰哥", age : 27, gender : true },
        ]
    },
    mutations : {
        increment(state) {
            state.count++;
        },
        decrement(state) {
            state.count--;
        }
    },
    getters : {
        getStudentByAge(state) {
            return state.studentList.filter(e => e.age > 24);
        }
    },
    actions : {
        increa(context) {
            context.commit('increment');
        },
        mp(context) {
            return new Promise(resolve => {
                setTimeout(() => {
                    context.commit("decrement");
                    resolve();
                }, 1000);
            });
        }
    }
});

export default store;

组件这里:

<template>
    <div>
        <h2>样本的标题</h2>
        <p>样本的标签</p>
        <p> <button @click="decrease">减少</button> {{$store.state.count}}  <button @click="increase">增加</button></p>
    </div>
</template>

<script>
    export default {
        name: "sample",
        methods : {
            decrease() {
                // this.$store.commit("decrement");
                this.$store.dispatch('mp').then(res => {
                   alert("数据跟新完毕"); 
                });
            },
            increase() {
                // this.$store.commit("increment");
                this.$store.dispatch('increa');
            }
        }
    }
</script>

<style scoped>

</style>

每次点击减少按钮就会晚一秒执行,然后再弹窗警告:

 

【Modules】

模块,vuex使用了单一状态树,当我们的状态过多时,使用store管理可能臃肿,这时候可以按照模块区划分vuex的store数据

当然,store还是可以统一管理module的

每个module即一个小的vuex,都具备上面的那些属性【getters,state,actions . . .】

import Vue from 'vue';
import VueX from 'vuex';

Vue.use(VueX);

const user = {
    state : {
        studentList : [
            { id : 1, name : "张三", age : 23, gender : true },
            { id : 2, name : "李四", age : 24, gender : true },
            { id : 3, name : "王五", age : 25, gender : true },
            { id : 4, name : "阿伟", age : 26, gender : true },
            { id : 5, name : "杰哥", age : 27, gender : true },
        ],
        token : "",
        name : '',
        header : '',
    },
    getters : {
        getStudentByAge(state) {
            return state.studentList.filter(e => e.age > 24);
        }
    }
}

const baseData = {
    state : {
        count : 0,
    },
    mutations : {
        increment(state) {
            state.count++;
        },
        decrement(state) {
            state.count--;
        }
    },
    actions : {
        increa(context) {
            context.commit('increment');
        },
        mp(context) {
            return new Promise(resolve => {
                setTimeout(() => {
                    context.commit("decrement");
                    resolve();
                }, 1000);
            });
        }
    }
}

const store = new VueX.Store({
    modules : {
        user,
        baseData
    }
});



export default store;

组件中的调用也需要更改:

      <p> {{$store.state.baseData.count}} </p>
      <p> {{$store.getters.getStudentByAge}} </p>

 

如果再index.js有太多的模块,可以抽取成文件,引入使用:

 

posted @ 2020-07-27 11:30  emdzz  阅读(122)  评论(0编辑  收藏  举报