zoukankan      html  css  js  c++  java
  • vuex的用法

      Vuex它是专门为Vue.js应用程序设计的状态管理工具。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。通俗来讲当有很多组件,组件与组件之间需要进行相互通信,这时就可以用到Vuex保存多个组件的共享状态,这时只需求state就可以在组件之间同步状态了。

      vuex的特点是把数据单独的隔离形成一棵树状图,单独隔离这就说明它有自己的生态系统,其中action作为数据输入,state作为数据输出。只能在mutations里修改state,actions不能直接修改state。在mutations中修改state的数据,它只能是同步操作,不能存在异步的操作(但如果是异步也不会报错,只是不建议)。如果是异步的操作,那可以把操作放在action中,拿到数据再通过mutations同步进行处理。下面我们来详细分析vuex的用法及核心概念。

      一、基本使用

      1、安装 npm install vuex --save

      2、在src目录下新建一个vuex的目录store并进行资源的引入,通过Vue.use()安装

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

      3、安装vuex后,创建一个store.

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

      4、为了在vue组件中访问,vuex提供了一个从根组件向所有子组件,以store选项的方式“注入”store

    new Vue({
        el:'#app',
        store:store,
    })    

      每一个vuex应用的核心就是store(仓库)。store它就是一个容器,包含着应用中大部分的state(状态)。vuex的状态存储是响应式的,当vue组件从store中读取state,state发生变化 ,那相应的组件也会变化更新。不能直接的改变仓库中的state,改变的唯一方法就是显示的提交mutation.这样可以方便跟踪每一个状态的变化。来面来分别介绍这些概念。

      二、核心概念

      1、state

      vuex使用单一状态树,用一个对象包含全部的应用层级状态。state它是这一状态管理工具唯一的数据源,所有的数据都存储在这里面。这说明了,每个应用将仅仅包含一个store实例。那如何在vue组件中展示呢?由于vuex是响应式的,最简单的方法是在计算属性中返回某个状态。 

    创建一个名show的组件
    <template>
       <div>
           <h1>{{this.$store.state.count}}</h1>
       </div>
    </template>
    <script>
    export default{
       name: 'show',
       computed:{
           count(){
               return this.$store.state.count
           }
       }
    }
    </script>
    <style lang='less'></style>

      当this.$store.state.count发生变化时,都会重新计算属性,触发更新相关联的DOM.

      如果一个组件需求获取的状态有多个时,如果把这些状态都声明为计算属性,那会很冗余,所以我们可以用发mapState辅助函数来帮助计算属性,mapstate其实就是把state中的属性映射到computed中。在使用它之前先在进行引入。如下所示:

    index.js
    export default new Vuex.Store({
       state: {
        //这里放置的是公用数据
        count:100,
        from:'china'
        
      } 
    })
    -------------------------------------------
    show.vue
    <template>
      <div>
            <h1>{{count}}</h1>
            <h3>{{sex}}</h3>
            <h3>{{from}}</h3>
      </div>
    </template>
    <script>
    import { mapState } from "vuex";
    export default {
      name: "show",
      data() {
        return {
          str: "国籍"
        };
      },
      computed: mapState({
        //第一种写法
        count: "count", //当名字一样时
        //第二名写法,使用箭头函数
        sex: state => state.from,
        //第三种写法,使用普通函数(this指向实例)
        from: function(state) {
          return this.str + ":" + state.from;
        }
      })
    };
    </script>
    <style lang='less'></style>

      当然computed不会因为引入了mapState辅助函数而失去原有的功能,但mapstate函数返回的是一个对象,这两者要如何混合使用呢?这时,需求使用一个工具函数将多个对象合并为一个,将最终对象传给computed属性。如下所示:

    computed: {
      localComputed () { 
         //......  
     },
         // 使用对象展开运算符将此对象混入到外部对象中
           ...mapState({
          // ......
      })
    }

      2、getter

      有时候需求从store中的state中派生出一些状态,所以要用到getter,getter是store的计算属性,getter返回的值会会根据依赖被缓存起来,只有当它的依赖值发生改变才会被重新计算。它的使用方法是 $store.getters.属性名。它可带参数,也可以不带参数,接受state为其第一个参数,也可以接受其它getter作为第二个参数。

    //index.js
    export default new Vuex.Store({
      state: {
        list: [1, 2, 3, 5, 6, 7, 8, 9, 0]
      },
      getters: {
        fillteredList: (state, getters)=>{
          console.log(state,getters);
          return state.list.filter(item => item > 5)
        }
      }
    })
    --------------------------------
    //show.vue
    <template>
      <div></div>
    </template>
    <script>
    // import { mapState } from "vuex";
    export default {
      name: "show",
      computed:{
          list(){
              return this.$store.getters.filteredList;
          }
      }
    };
    </script>
    <style lang='less'>
    </style>

      我们可以通过mapGetters辅助函数将store中的getter映射到局部计算属性,使用前还是要进行引入。

    import { mapGetters } from 'vuex'
    export default {
      // ...
      computed: {
      // 使用对象展开运算符将 getter 混入 computed 对象中
        ...mapGetters([
        //如果想将一个getter属性另取一个名字,使用对象形式
         doneCout:'donetodoCount'
          // ...
        ])
      }
    }
        

      3、mutation

      我们知道更改vuex中store状态的唯一方法就是提交mutation.vuex中的mutation类似于事件,每个mutation都有一个字符串的事件类型(type)和一个回调函数(handler),这个回调函数就是实际进行状态更改的地方,可以看成是{type:handler()},调用type时用到store.commit方法。

    //index.js
    export default new Vuex.Store({
      state: {
        //这里放公用的数据
        count: 100,
        age: 20
      },
      mutations: {
        //这里面的函数都是用来修改state中状态的
        //用this.$store.commit()方法触发
        changeCount(state, option) {
          //state是我们公用状态,option是执行这个函数时传递的值,最多只有两个参数,最少为一个
          console.log(state, option);
          console.log(arguments);
          // state.count += option;
          state.count += option.num;
    
        }
      }
    })
    -----------------------------------------------
    button.vue
    <template>
      <div>
        <button @click="add">增加</button>
        <button @click="minus">减少</button>
        <h2>{{res}}</h2>
      </div>
    </template>
    <script>
    export default {
      name: "xxx",
      computed:{
          res(){
              return this.$store.state.count;
          }
      },
    //在methods中提交 methods: { add() {
    //commit()执行会默认去mutations中查找对应的函数并执行 // this.$store.commit("changeCount",10); //还可以改变风格 this.$store.commit({type:'changeCount',num:100}) }, minus() { // this.$store.commit("changeCount", -10); this.$store.commit({type:'changeCount',num:-100}) } } }; </script> <style lang='less'></style>

      需求注意的是mutation必须是同步的,这是为了调试方便。在项目中使用时,一般将常量放在单独的文件中,这样更有助于协作开发,提高效率。

    //mutation-type.js
    export const some_mutation = 'some_mutation'
    //store.js
    import Vuex from 'vuex'
    import { some_mutation } from './mutation-type'
    
    let store = new Vuex.Store({
      state: {......},
      mutations: {
        [some_mutation](state, option) {
          //......
        }
      }
    })

     可以使用mapMutations辅助函数。它的作用是把mutations中的方法映射到组件的methods中。使用辅助函数之前还是要先引入,如下所示:

    <template>
      <div>
        <button @click="add(30)">增加</button>
        <button @click="minus">减少</button>
        <button @click="changeCount(50)">test</button>
        <h2>{{res}}</h2>
      </div>
    </template>
    <script>
    import {mapMutations} from 'vuex'
    export default {
      name: "xxx",
      computed:{
          res(){
              return this.$store.state.count;
          }
      },
      methods: {
          ...mapMutations(['changeCount']),
          ...mapMutations({add:'changeCount'}),
        // add() {
        //  this.$store.commit('changeCount',100);
        // },
        minus() {
          this.$store.commit("changeCount", -10);
        }
      }
    };
    </script>
    <style lang='less'></style>

      4、action

      actions是为异步操作而设置的。因为mutations只能是同步操作,但在实际的项目中会存在异步操作,这样就变成了在action中去提交mutation,然后在组件的methods中去提交action。只在在提交的时候使用的是dispatch函数,而mutations使用的是commit函数.

    actions:{
        //这里面的函数最终都会触发mutations中的函数
        //这些函数中原则上不能直接修改state中的数据
        //通过this.$store.dispatch()
        changeCount(store, option){
          //console.log(store, option);
          setTimeout(() => {
            store.commit('changeCount',option)
          }, 200);
          // console.log(arguments)
        }
      }
    --------------------------------------
      methods: {
        add() {
        this.$store.dispatch('changeCount',100,200);
        },
        minus() {
        this.$store.dispatch('changeCount',-100);
    
        }
      }

      5、module

      由于vuex使用了单一状态树,应用的所有状态都会集中到一个比较大的对象中,当应用比较复杂的时候,store对象就会变的十分的臃肿。所以才有了module,它可以将store分割成模块,每个模块有自己的state,getter,mutation,action甚至是嵌套的子模块,从上到下进行同样方式的分割。它主要是进行模块的划分。

    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 的状态

      对于模块内部的mutation和getter来说,接受的第一个参数是模块的局部状态state。根结点的状态为rootState。

      总结一下,对于含有vuex的项目来说,其结构大体如下:1、应用层级的状态都应该集中在store2、提交mutation是更改state的唯一方式 3、异步操作应试放在action里。如果store文件过大,可以将action,mutation,getter进行分割,分割到单独的文件中。

      

      

      

     

  • 相关阅读:
    vue中watch的详细用法
    Golang实现请求限流的几种办法
    观察者模式
    原创-阿里云上SLB暴露K8S服务-四层协议/七层协议
    K8S-HPA创建指南
    阿里云k8s-nas挂载指南
    非原创--mysql语言分类
    mysql命令
    MongoDB从节点支持读请求
    MongoDB用户权限管理
  • 原文地址:https://www.cnblogs.com/davina123/p/13384554.html
Copyright © 2011-2022 走看看