6--Vuex

作者: Daeeman | 来源:发表于2020-03-29 21:35 被阅读0次

    Vuex(状态管理模式)

    Vuex 的核心由五部分组成:State、Getter、Mutation、Action 和 Module。

    1. Vuex概述

    1.1 组件之间数据共享的方式

    父向子传值:v-bind 属性绑定
    子向父传值:v-on 事件绑定
    兄弟组件之间共享数据:EventBus

    • $on 接受数据的那个组件
    • $emit 发送数据的那个组件
    1.2 Vuex是什么
    image.png
    1.3 使用 Vuex 统一管理状态的好处

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

    1.4 什么样的数据适合存储到Vuex中

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

    2. Vuex 的基本使用

    1 . 安装vuex依赖包
    npm install vuex --save
    
    2 . 导入vuex包
    import Vuex from 'vuex'
    Vue.use(Vuex)
    
    3 . 创建store对象
    const store = new Vuex.Store({
        //state中存放的就是全局共享的数据
        state:{count}
    })
    
    4 . 将store 对象挂载到 vue 实例中
    new Vue({
        el:'#app',
        render:h=> h(app),
        router,
        //将创建的共享数据对象,挂载到vue实例中
        //所有的组件,就可以直接从store中获取全局的数据了
        store
    });
    

    .prettierrc

    {
        "semi":false,  //去分号
        "singleQuote":true,//单引号替换双引号
    }
    
    store.js main.js
    image.png image.png

    3 . Vuex 的核心概念

    3.1 核心概念概述

    State,Getter,Mutation,Action,Module

    主要核心概念:

    • state:包含了store中存储的各个状态。
    • getter: 类似于 Vue 中的计算属性,根据其他 getter 或 state 计算返回值。
    • mutation: 一组方法,是改变store中状态的执行者,只能是同步操作。
    • action: 一组方法,其中可以包含异步操作。


      image.png

    3.2 State

    State提供唯一的公共数据源,所有共享的数据都要统一放到 Store 的 State 中进行存储

    //创建store唯一的共享数据源,提供唯一公共数据
    const store = new Vuex.Srore({
        state:{count:0}
    })
    
    a. 组件访问State中数据的第一种方式
    this.$store.state.全局数据名称
    
    <template>
        <div>
            <h3>当前count值为:{{$store.state.count}}</h3>
            <button>+1</button>
        </div>
    </template>
    
    <script>
    export default {
        data() {
            return {}
        }
    }
    </script>
    
    注: template里面 this可以省略

    3.2 . State

    image.png
    <template>
        <div>
            <h3>当前count值为:{{count}}</h3>
            <button>-1</button>
        </div>
    </template>
    
    <script>
    import {mapState} from 'vuex'
    export default {
        data() {
            return {}
        },
        computed:{
            ...mapState(['count'])
        }
    }
    </script>
    
    image.png
    ⚠️ 注意 :不可以在methods中直接通过 this.$store.state.count++ 来直接修改store中的数据(虽然并不会报错),store中的数据只能通过mutations修改
    store.js Addition.vue
    image.png image.png
    image.png
    store.js Addition.vue
    image.png
    store.js image.png
    image.png
    export default new Vuex.store({
      state:{
        count:0
    },
    //只有 mutations 中定义的函数,才有权利修改 state 中的数据
    mutations:{
        add(state){     //不要在 mutations 函数中,执行异步操作
        //setTimeout(()=>{
        //   state.count++
        // },1000)
        state.count++
        },
        addN(state,step){
            state.count += step
        }
    },
    actions:{
        addAsync(context){        //在 action 中,不能直接修改 state 中的数据
          setTimeout(()=>{        //必须通过 context.commit() 触发某个 mutation才行 
            context.commit('add')
        },1000)
      },
        addNAsync(context,step){
            setTimeout(()=>{
                context.commit('addN',step)
            },1000)
        }
    }
    })
    
    btnHandle1(){
        this.$store.commit('add')
    },
    btnHandler2(){
         //commit的作用,就是调用 某个 mutation函数
        this.$store.commit('addN',3)
    },
     //异步的让 count 自增 +1
    btnHandler3(){
        this.$store.dispatch('addAsync')
        //这里的dispatch函数,专门用来触发action
    }
    btnHandler4(){
          this.$store.dispatch('addNAsync',5)
    }
    
    action带参 action
    export default new Vuex.store({
      state:{
        count:0
    },
    //只有 mutations 中定义的函数,才有权利修改 state 中的数据
    mutations:{
        add(state){     //不要在 mutations 函数中,执行异步操作
        //setTimeout(()=>{
        //   state.count++
        // },1000)
        state.count++
        },
        addN(state,step){
            state.count += step
        },
        sub(state){
            state.count --
        },
        subN(state,step){
            state.count -= step
        }
    },
    actions:{
        addAsync(context){        //在 action 中,不能直接修改 state 中的数据
          setTimeout(()=>{        //必须通过 context.commit() 触发某个 mutation才行 
            context.commit('add')
        },1000)
      },
        addNAsync(context,step){
            setTimeout(()=>{
                context.commit('addN',step)
            },1000)
        },
        subAsync(context){
            setTimeout(()=>{
            context.commit('sub')
            },1000)
        },
        subNAsync(context,step){
            setTimeout(()=>{
            context.commit('subN',step)
            },1000)
        }
    }
    })
    
    <div>
            <h3>{{count}}</h3>
            <button @click="btnHandler1">-1</button>
            <button @click="btnHandler2">-1</button>
            <button @click="btnHandler3">-1</button>
            <button @click="subNAsync(5)">-1</button>
    </div>
    <script>
    import {mapState,mapMutations,mapActions} from 'vuex'
    export default {
    data(){
        return {}
    },
    computed:{
    ...mapState(['count'])
    },
    methods:{
        ...mapMutations(['sub','subN']),
        ...mapAction(['subAsync','subNAsync']),
        btnHandle1(){
            this.sub()
        },
        btnHandler2(){       
            this.sub(3)
        },    
        btnHandler3(){    
            this.subAsync()
        }
    }
    }
    </script>
    
    <button @click="subAsync">-1</button>
    ...mapAction(['subAsync']),
    subAsync() {}
    
    
    image.png image.png

    3.6 Module

    • 由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

    • 这时我们可以将 store 分割为模块(module),每个模块拥有自己的 stategettersmutationsactions 、甚至是嵌套子模块——从上至下进行同样方式的分割。

    代码示例:

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

    https://blog.csdn.net/u010358168/article/details/107249106

    https://www.bilibili.com/video/BV1h7411N7bg?p=14

    相关文章

      网友评论

          本文标题:6--Vuex

          本文链接:https://www.haomeiwen.com/subject/rxlpuhtx.html