zoukankan      html  css  js  c++  java
  • Vue(十五):Vuex

    1、Vuex是个啥
      Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,类似于弄了一个全局的缓存库,缓存库中数据的改变---会实时改变---组件中因为使用该数据而产生的状态,达到一种牵一发而动全身的效果。

    2、Vuex的使用
      首先我们需要使用“npm install vuex --save"命令来安装vuex。vuex的核心概念是state、getter、mutation、action、module这五个概念,我们在下面放了一些基础的代码示例,再通过介绍来了解他们。

    1)、state
      state相当于组件中的data,以代码示例中的count为例,我们可以通过this.$store.state.count来访问该值,但是值得注意的是我们只能读取,不能直接修改。我们还可以使用mapState辅助函数帮助我们生成计算属性,需要import { mapState } from 'vuex'。举例举例:

    computed:mapState({
            count:(state)=>state.count,
            countAlias:'count',
            countAdd2(state){
                return state.count+2;
            },
        }),

    2)、getter
      getter相当于组件中的computed,有时候我们需要直接在store中过滤一些数据,我们就可以直接使用getter,且getter中的数据会被缓存。就像在示例代码中写的那样,getter的第一个参数是state,后面的参数我们可以在调用的时候传进去。以代码示例中的nameTodos为例,我们可以通过this.$store.getters.nameTodos来访问该值,我们还可以使用mapGetters辅助函数帮助我们生成计算属性,需要import { mapGetters } from 'vuex'。举例举例:

    <span v-for="todo in $store.getters.nameTodos" :key="todo.id">{{todo}}</span><br> //html代码
    <span v-for="todo in $store.getters.getTodoById(2)" :key="todo.id">{{todo}}</span><br>
    <span v-for="todo in maxNameTodos" :key="todo.id">{{todo}}</span><br>
    //vue示例中代码
    computed:mapGetters({
            maxNameTodos:'maxNameTodos'
        }),
    

    3)、mutation
      mutation相当于组件中的methods,刚才我们就说过了不能直接更改state中的值,怎么更改呢?就通过mutation中的方法更改。就像在示例代码中写的那样,mutation的第一个参数是state,后面的参数我们可以在调用的时候传进去。以代码示例中的increment为例,我们可以通过this.$store.commit('increment')来访问该方法,我们还可以使用mapMutations辅助函数帮助我们生成计算属性,需要import { mapMutations} from 'vuex'。需要注意的是,mutation中的方法必须是同步的,不能是异步方法。举例举例:

    <span>{{$store.state.count}}</span>  //html代码
    <button @click="Add1">+1</button>
    <button @click="Add2">+10</button>
    <button @click="Add3">+2</button>
    <button @click="Add4">+1</button>
    //vue示例代码
    methods:mapMutations({
            Add1(){
                this.$store.commit('increment');
            },
            Add2(){
                this.$store.commit('incrementObj',{count:10});
            },
            Add3(){
                this.$store.commit(Mutations.SOME_MUTATION);
            },
            Add4:'increment',
        }),
    

    4)、action
      刚才我们说了mutation不能是异步操作,那谁来进行呢?action。action不是直接修改state,action也是直接提交的mutation。需要注意的是action的第一个参数是context,它是一个和store具有相同属性和方法的另一个对象,所以他也能调用mutation中的方法。以代码示例中的incrementObj为例,我们可以通过this.$store.dispatch('incrementObj')来访问该方法,我们还可以使用mapActions辅助函数帮助我们生成计算属性,需要import { mapActions} from 'vuex'。举例举例:

    <span>{{$store.state.count}}</span> //html代码
    <button @click="Add5">+10</button>
    <button @click="Add6">+11</button>
    //vue示例代码
    methods:mapActions({
            Add5(){
                this.$store.dispatch('incrementObj',{count:10}).then((s)=>{alert(s)});
            },
            Add6(){
                this.$store.dispatch('increment12',{count:10});
            }
        }),

    5)、代码示例
      首先我们要在src目录下建立store文件夹,然后建立store.js文件

    import Vue from "vue";    //store.js
    import Vuex from "vuex";
    import * as Mutations from '@/store/mutation-types.js'
    Vue.use(Vuex);
    var store = new Vuex.Store({
        state:{
            count:1,
            todos:[
                {id:1,name:"张三"},
                {id:2,name:"李四"},
                {id:3,name:"王二麻子"},
            ]
        },
        mutations:{
            increment(state){
                state.count++;
            },
            incrementObj(state,obj){
                state.count+=obj.count;
            },
            [Mutations.SOME_MUTATION](state){
                state.count+=2;
            }
        },
        getters:{
            nameTodos:state=>{
                return state.todos.filter(v=>v.id<=1);
            },
            getTodoById:(state)=>(id)=>{
                return state.todos.filter(v=>v.id==id);
            },
            maxNameTodos:state=>{
                return state.todos.filter(v=>v.id>2);
            },
        },
        actions:{
            incrementObj(context,obj){
                return new Promise((resolve, reject)=>{
                    setTimeout(() => {
                        context.commit('incrementObj',obj);
                        resolve('success');
                    }, 1000);
                })
            },
            increment12(context,obj){
                context.dispatch('incrementObj',obj).then(()=>{
                    context.commit('increment');
                });
            },
        },
    });
    
    export default store;
    

     然后在main.js中引入store

    import Vue from 'vue'
    import App from './App'
    import store from './store/store.js'
    new Vue({
      el: '#app',
      store,
      components: { App },
      template: '<App/>',
    })
    

    6)、module
      vuex允许我们将store分割成模块,这样我们做大型项目的时候容易管理。基本理念呢就是建立一个新的store对象,然后汇总引入到最顶级的store对象中,加在module属性中,就像组件一样。我们下面呢通过动态注册,将vuex的状态同步vue的示例中,获取全局的属性和方法。
    首先在store文件夹下建立modules文件夹,然后建立一个TestStore.js。写个简单的代码:

    export default {
        state: {
            count: 1,
        },
        getters: {
            store_test_count(state) {
                return state.count
            },
        },
    };
    

    然后引入到store.js中,在store对象导出之前,动态注册一下,注册完之后,我们就能全局访问getters中的store-test-count了。代码如下:

    import Test from "@/store/modules/Test.js";
    store.registerModule("Test", Test);
    

    后面我们在store文件夹下建立mappings文件夹,然后建立一个Test.js,这实际是一个vue的示例。写个简单的代码:

    import { mapGetters } from 'vuex'
    export default {
        computed: mapGetters([
            'store_test_count',
        ]),
    }
    

    这个时候呢,我们的这个js通过获取store中的属性就有了一个叫store-test-count的计算属性。我们把这个属性在main.js中混合到App示例中之后就是全局的计算属性了。我们建立一个引导的js文件,叫storeMapping.js。上代码吧:

    import Test from "@/store/mappings/Test.js";   //storeMapping.js
    export default {
        initMixins(Vue) {
          Vue.mixin(Test);
        }
      };
    //main.js
    import storeMapping from './store/storeMapping.js'
    storeMapping.initMixins(Vue);  //在创建App示例前调用
    

      

  • 相关阅读:
    LiteFlow 按照规则配置进行复杂流转
    ImageCombiner 服务端合图
    forest HTTP调用API框架
    smart-doc API文档生成工具
    YAML语法和用法
    拓展mybatisPlus 支持批量插入
    ModbusRTU控制SV660P说明
    .NET RulesEngine(规则引擎)
    Win10自动更新有效强制永久关闭
    Redis 到底是怎么实现“附近的人”这个功能的?
  • 原文地址:https://www.cnblogs.com/liangshibo/p/13086981.html
Copyright © 2011-2022 走看看