zoukankan      html  css  js  c++  java
  • 【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有太多的模块,可以抽取成文件,引入使用:

  • 相关阅读:
    常见的四种文本自动分词详解及IK Analyze的代码实现
    用java语言通过POI实现word文档的按标题提取
    spark的运行模式
    团队冲刺日志2
    简单之美-软件开发实践者的思考 03
    简单之美-软件开发实践者的思考 02
    简单之美-软件开发实践者的思考 01
    学习进度 15
    构建之法 06
    构建之法 05
  • 原文地址:https://www.cnblogs.com/mindzone/p/13384362.html
Copyright © 2011-2022 走看看