zoukankan      html  css  js  c++  java
  • VueX入门

    VueX入门

    VueX是什么?

    Vuex 是用于集中管理组件之间数据的一个组件,通过Vue可以完成父子、子父、兄弟等任何复杂关系的组件之间数据传递问题。

    • VueX可以集中管理共享数据,易于开发和后期维护。
    • 能够高效的实现组件之间的数据共享,提高开发效率
    • 存储在VueX中的数据都是响应式的,能够时时保持数据与页面的同步

    什么样的数据适合存放在VueX中

    一般情况下,只有组件之间共享的数据,才有必要存储在VueX中,对于组件中私有的数据,依旧存放在自身的data中即可。

    VueX的使用

    1、安装依赖包

    npm install vuex --save
    

    2、导入vuex包

    这一步一般我们会在src下创建一个名为store的文件夹,在其内创建一个index.js(安装好vuex插件后,一般都会默认创建了。)

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    

    3、创建store对象

    这一步同样是在src/store/index.js中创建的

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
      state: {
      },
      mutations: {
      },
      actions: {
      },
      modules: {
      }
    })
    

    4、将store对象挂载到vue实例中

    这一步一般在main.js中进行全局配置,别忘了引入store

    import store from './store'
    ...
    
    new Vue({
      router,
      store,//ES6语法引入
      render: function (h) { return h(App) }
    }).$mount('#app')
    

    state

    Vue中的store是用于统一存放数据的仓库,用于组件之间的参数传递。可以理解为所有组件中共有参数的公共容器。store中的属性默认是只读的,如果要操作,需要使用mutations。(vuex如果没有开启严格模式的话是可以直接修改state中的值的但是强烈不推荐这样做)

    state数据的创建

    在state中创建属性:以下内容引用自src/store/index.js

    export default new Vuex.Store({
      state: {
          count: 0
      }
        ...
    })
    

    state数据的访问

    组件内访问

    this.$store.state.全局数据名称
    

    如果是在html元素组件之间调用,则可以省略this

    <span>{{$store.stat.全局数据名称}}</span>
    

    mapState辅助函数

    mapState访问

    通过mapState辅助函数方式,实现组件访问State中数据的第二种方式关于mapsState的详细讲解

    // 1. 从vuex中按需导入mapState函数
    import { mapState } from 'vuex'
    

    通过刚才导入的mapState函数,将当前组件需要的全局数据,映射为当前的computed计算属性:(注意这里的...必须要加,不是代表省略其他代码的意思)

    // 2. 将全局数据映射为当前组件的计算属性
    computed: {
        // ...表示展开映射,意思就是将全局属性映射为当前组件的计算属性
        ...mapState(['count'])
    }
    

    直接在调用获取组件属性

    <span>{{count}}</span>
    

    使用了mapState后,值可以进行watch监听。

    import { mapState } from 'vuex'
    export default {
        name:"VueXPage",
        components:{
    
        },
        methods:{
            test(){
                this.$store.state.count++;
            }
        },
        computed:{
            ...mapState(['count'])
        },
        watch:{
            count(oVal,nVal){
                console.log(oVal + "," + nVal);
            }
        }
    }
    

    Mutations

    VueX中的mutations是用于变更Store中的数据。

    在VueX中,只能通过mutations变更store数据,不可以直接操作store中的数据。虽然通过mutations的方式操作数据,虽然繁琐了一些,但是可以集中监控所有数据的变化。

    例如要让全局数据自增1,则可以通过如下的方式在mutations中定义(以下代码来自/src/store/index.js)

    export default new Vuex.Store({
      state: {
          count: 0
      },
      mutations:{
          increment(state){
              //修改state
              state.count++;
          }
      }
    })
    

    定义完mutations之后,我们介绍以下如何在组件中触发~

    方式1、通过$store.commit()函数触发mutations

    组件代码:在组件中创建一个函数,然后通过@click等事件触发机制来调用

    methods: {
        handle1 () {
            // 触发mutations的第一种方式
            this.$store.commit('increment')
        }
    }
    

    带参数的调用:

    export default new Vuex.Store({
      state: {
          count: 0
      },
      mutations:{
          increment(state){
              //修改state
              state.count++;
          },
          incrementVal(state,num){
              //增加具体的值
              state.count += num;
          }
      }
    })
    

    在组件中是使用:

    methods: {
        handler2: {
            this.$store.commit('incrementVal', 5);
        }
    }
    

    方式2:通过mapMutations辅助函数触发

    上面我们介绍了mapState,Mutations中同样提供了辅助函数来简化操作。

    // 1. 从vuex中按需导入mapMutations函数
    import { mapMutations } from 'vuex'
    
    ...
    
    // 2. 将制定的mutations函数映射为当前组件的methods函数
    methods: {
        // 将add和addN方法映射为methods中的函数,拱当前组件使用。
        ...mapMutations(['increment','incrementVal']),
        handleAdd() {
            this.increment();
        },
        handleAddN(n) {
            this.incrementVal(n);
        }
        // 或者直接在标签元素中直接@click=add()
    }
    

    对于mutations来说,只能够实现同步操作,不可以执行异步操作的。

    Actions

    从vuex官网中可以了解到,Actions类似于mutations,不同之处在于:

    • Actions 提交的是 mutation,而不是直接变更状态。
    • Actions 可以包含任意异步操作。

    可以得出一个结论就是,如果通过异步操作变更数据,必须通过Actions,而不能使用Mutations,但是在Actions中还是要通过触发Mutations的方式间接变更数据。

    定义actions

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
      state: {
        count:0
      },
      mutations: {
        increment(state){
          state.count++;
        },
        incrementVal(state,num){
          state.count += num;
        }
      },
      actions: {
        incrSync(context){
          setTimeout(()=>{
            context.commit('increment');
          },1000);
        },
        incrValSync(context,num){
          setTimeout(()=>{
            context.commit("increment",num);
          },1000);
        }
      },
      modules: {
      }
    })
    
    

    需要再次强调的是,只有通过mutations中定义的函数,才有权利去修改state中的数据,因此actions最终还是要调用mutations。

    触发Actions

        methods:{
            ...mapMutations({increment:'increment',incrementVal:'incrementVal'}),
            test(){
                this.$store.state.count++;
            },
            incr(){
                this.increment();
            },
            incrVal(num){
                this.incrementVal(5);
            },
            syncIncr(){
                this.$store.dispatch('incrSync');
            },
            syncIncrVal(num){
                this.$store.dispatch('incrValSync',num);
            }
        }
    

    触发Actions的第二种方式

    Actions同样拥有辅助函数,mapActions。

    // 1. 从vuex中按需导入mapActions函数
    import { mapActions } from 'vuex'
    
    ...
    
    // 2. 将指定的actions函数,映射为当前组件的methos函数
    methods: {
        ...mapActions(['incrSync', 'incrValSync']),
        handleAddAsync() {
            this.addAsync();
        },
        handleAddNAsync(n) {
            this.addNAsync(n);
        }
    }
    

    Getter

    在Vuex官网中,用到了派生这一词来介绍Getter,在这里可以理解为就是用于对Store中的数据进行加工处理,形成新的数据,类似Vue的计算属性。Getter的数据是基于Store中的数据的,所以当Store中数据发生变化时,Getter中的数据也会随之变化。

    定义Getter

    例如state中存有todos计划项,其对象有一个done状态表示完成与否。

    const store = new Vuex.Store({
      state: {
        todos: [
          { id: 1, text: '...', done: true },
          { id: 2, text: '...', done: false }
        ]
      },
      getters: {
        // 这里通过getters定义的doneTodos方法来过滤已完成的todo项
        doneTodos: state => {
          return state.todos.filter(todo => todo.done);
        },
        // 这里还可以通过传入getters对象来获取其他方法
        doneTodosCount: (state, getters) => {
            return getters.doneTools.length;
        },
        // 传入参数
        getTodoById: (state) => (id) => {
            return state.todos.find(todo => todo.id == id);
        }
      }
    })
    
    

    触发Getter定义函数的第一种方法**

    this.$store.getters.doneTodos // -> [{id: 1, text: '...', done: true}]
    this.$store.getters.doneTodosCount // -> 1
    

    触发Getter定义函数的第二种方法**

    通过mapGetters来触发Getter中定义的函数

    // 1. 导入mapGetters辅助函数
    import { mapGetters } from 'vuex'
    
    ...
    
    // 2. 将制定的Getters函数映射为当前组件的函数
    methods: {
        ...mapGetters(['doneTodos', 'doneTodosCount']),
        handleDoneTodos() {
            this.doneTodos();
        }
    }
    
    
    

    Modules

    当Store中存放了非常多非常大的共享数据对象时,应用会变的非常的复杂,Store对象也会非常臃肿,所以Vuex提供了一个Module模块来分隔Store。通过对Vuex中的Store分隔,分隔成一个一个的Module模块,每个Module模块都拥有自己的state、mutation、actions和getters。

    const moduleA = {
      state: () => ({ ... }),
      mutations: { ... },
      actions: { ... },
      getters: { ... }
    }
    
    const moduleB = {
      state: () => ({ ... }),
      mutations: { ... },
      actions: { ... }
    }
    
    const store = new Vuex.Store({
      modules: {
        a: moduleA,
        b: moduleB
      }
    })
    
    store.state.a // -> moduleA 的状态
    store.state.b // -> moduleB 的状态
    
    

    对于模块中的mutations和getters,传入的第一个参数规定为state,而actions则依旧是context参数。如下:

    const moduleA = {
      state: {
         count: 0
      },
      mutations: {
        increment (state) {
          // 这里的 `state` 对象是模块的局部状态
          state.count++
        }
      },
    
      getters: {
        doubleCount (state) {
          return state.count * 2
        }
      },
      actions: {
      	// context对象其实包含了 state、commit、rootState。
      	incrementIfOddRootsum (context) {
    		if ((context.state.count + context.rootState.count) % 2 === 1) {
            // 调用mutations
            commit('increment')
          }
      	}
      }
    }
    
    

    第一种调用方式

    在module中通过mapState、mapGetters、mapActions和mapMutations等辅助函数来绑定要触发的函数**

    methods: {
    	...mapActions([
    		'some/nested/module/foo',
    		'some/nested/module/bar'
    	])
    }
    
    

    在vuex中,可以为导入的state、getters、actions以及mutations命名别名,,这样可以方便调用

    methods: {
    	...mapActions([
    		'foo': 'some/nested/module/foo',
    		'bar': 'some/nested/module/bar'
    	])
    }
    
    

    第二种调用方式

    对于这种情况,你可以将模块的空间名称字符串作为第一个参数传递给上述函数,这样所有绑定都会自动将该模块作为上下文。于是上面的例子可以简化为:

    methods: {
      ...mapActions('some/nested/module', [
        'foo', // -> this.foo()
        'bar' // -> this.bar()
      ])
    }
    

    第三种调用方式

    可以通过使用 createNamespacedHelpers 创建基于某个命名空间辅助函数。它返回一个对象,对象里有新的绑定在给定命名空间值上的组件绑定辅助函数:

    import { createNamespacedHelpers } from 'vuex'
    
    const { mapState, mapActions } = createNamespacedHelpers('some/nested/module')
    
    export default {
      methods: {
        // 在 `some/nested/module` 中查找
        ...mapActions([
          'foo',
          'bar'
        ])
      }
    }
    

    总结

    1. Vuex主要用于管理Vue组件中共享的数据。
    2. Vuex中有state、mutation、action、getter等核心概念。
    3. 获取state可以通过this.$store.state.xx或者是通过定义mapState来获取。
    4. 修改state中的变量需要通过mutation函数实现,而mutation的触发由两种方式,一种是通过this.$store.commit()函数,另外一种就是通过mapMutations来实现。
    5. mutation只能用于修改数据,而Actions可以实现异步操作。
    6. 通过Actions的异步操作+mutation的修改数据,可以实现异步修改数据。调用Actions有两种方式,第一种是通过this.$store.dispatch来调用,另外一种方式是通过mapActions来调用。
    7. Getters函数用于对Store中数据进行加工,不会修改原本Store中的数据;Getters中的数据会受Store中数据进行影响。
  • 相关阅读:
    Jmeter错误解析-明明写对了,确报404,原因是接口里多了个空格
    Jmeter+ant+svn+jenkins一键部署(四)--机器人发报告
    Django
    Linux下压缩解压文件夹+下载+删除命令
    VUE-安装
    Hadoop核心-MapReduce
    Pulsar 社区周报|2021-06-14~2021-06-20
    ApacheCon Asia 2021: Apache Pulsar 技术议题一览
    Pulsar 社区周报|2021-06-07~2021-06-13
    直播回顾|TGIP-CN 032:Apache Pulsar 快速上手实战
  • 原文地址:https://www.cnblogs.com/zhangruifeng/p/14334550.html
Copyright © 2011-2022 走看看