zoukankan      html  css  js  c++  java
  • vuex

    vuex-集中式管理数据

    vuex官网:https://vuex.vuejs.org/zh-cn/

    一、安装

    cnpm install vuex --save-dev

    二、vuex数据流示意图

    三、使用vuex

    import Vuex from 'vuex';
    Vue.use(Vuex);
    // 创建store实例 const store = new Vuex.Store({ // 存储state状态值   state: {
        ...
      },
    // 类似于事件集合,每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,是同步函数   mutations: {
        ...
      },
    // 更改store状态的唯一方法是提交mutation,mutation已经对状态进行更改,actions就是用来提交mutation的,可以包含任意异步操作。   actions: {
        ...
      },
    // 被认为是store的计算属性,getters接受state作为第一个参数   getters: {
        ...
      } })
    /* eslint-disable no-new */ new Vue({ // 使用store,将store实例注入到根组件下的所有子组件中 // 子组件可以通过this.$store来访问store对象 store // store:store (key:value,key和value名字相同时,可省略value) })

    四、核心概念

    1、state

    state负责存储所有的状态数据,可以直接用 this.$store.state 获取store的状态数据。

    html:
       <div>count: {{ count }}</div>
     
    script:
    // 创建store实例
    const store = new Vuex.Store({
        state:{
            count:0
        }
    })
    
    export default{
        computed:{
            count(){
                 return this.$store.state.count;
            }
        }
    };

    结果--> count:0

    也可以使用 mapState辅助函数 将state映射到计算属性中去。

    // 在单独构建的版本中辅助函数为 Vuex.mapState
    import { mapState } from 'vuex'
    
    export default {
      // ...
      computed: mapState({
        // 映射 this.count 为 store.state.count
        count: state => state.count
      })
    }

    2、getters

    getters被认为是store的计算属性,接受state作为第一个参数,对state进行二次加工,通过 this.$store.getters 访问。

    html:
       <div>用户名: {{ userName }}</div>
    
    script:
    // 创建store实例
    const store = new Vuex.Store({
        state:{
            name:'Jack'
        },
        getters:{  // 被认为是store的计算属性,对state数据进行二次处理,从而被其他地方进行调用
            userName(state){
                return state.name + ',Hello';
            }
        }
    })
    
    export default{
        computed:{
            userName(){
                return this.$store.getters.userName;
            }
        }
    };

     结果--->  用户名: Jack,Hello

    mapGetters 辅助函数 仅仅是将store中的getter映射到局部计算属性。

    import { mapGetters } from 'vuex'
    
    export default {
      // ...
      computed: {
      // 使用对象展开运算符将 getter 混入 computed 对象中
        ...mapGetters([
          // 映射 `this.doneTodosCount` 为 `store.getters.doneTodosCount`
          'doneTodosCount',// ...
        ])
      }
    }

    3、mutations

    mutations类似于事件,更改store状态的事件函数,是改变状态的唯一方法,每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数。只能是同步的。

    <div>数量: {{ count }}</div>
    
    export default{
        computed:{
            name(){
                return this.$store.state.count;
            }
        }
    }
    
    const store = new Vuex.Store({
      state: {
        count: 1
      },
      mutations: {
        increment (state) {
          // 变更状态
          state.count++
        }
      }
    })

    mutation更改了store 状态,并不代表更改成功,需要提交才能触发mutation的方法。

    在组件中提交mutation,你可以在组件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用。

    <a href="javascript:;" @click="click">点击</a>
    export default {
      methods: {
        click() {
          this.$store.commit('increment');
        }
      }
    }
    import { mapMutations } from 'vuex'
    
    export default {
      // ...
      methods: mapMutations([
          'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
        ])
    }
    
    <button @click="increment">点击</button>

    4、actions

    actions类似于mutations,用于改变状态,不过不同的是通过提交mutations来触发mutations改变store状态,可以包含任意异步操作。

    <div>数量: {{ count }}</div>
    <div>用户名: {{ name }}</div>
    
    const store = new Vuex.Store({
       state:{
            count:0,
            name:'Jack'
        },
        mutations:{   // 改变状态的唯一方法,但也要提交才有用
            increment(state){
                state.count++;
            },
            updateName(state,userName){  // 也可接受第二个参数
                state.name = userName;
            }
        },
        actions:{  // 提交mutations
            incrementAction(context){  // 提交increment,代替method的add点击事件中的this.$store.commit('increment');
                context.commit('increment');
            },
            updateNameAction(context,userName){  // 提交updateName
                context.commit('updateName',userName);
            }
        }
    })
    
    export default{
        computed:{
            count(){
                return this.$store.state.count;
            },
            name(){
                return this.$store.state.name;
            }
        }
    }

    actions通过 this.$store.dispatch('increment') 来触发,或者通过辅助函数 mapActions (与mapMutations类似) 将组件的 methods 映射为 store.dispatch 调用。

    <a href="javascript:;" @click="add">点击</a>
    
    export default{
        methods:{
            add(){
                // this.$store.commit('increment');  // 提交increment事件类型来触发mutations,实现count++
                // this.$store.commit('updateName','Tom'); // 用户名变成Tom
                
                // vuex中定义了actions提交mutations,这里就不需要提交mutations来触发事件了,只要触发actions就行
                this.$store.dispatch('incrementAction');
                this.$store.dispatch('updateNameAction','Tom');
            }
        }
    }
    import {mapActions} from 'vuex'
    
    export default {
      methods: mapActions([
        'increment',   // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
      ])
    }
    
    <button @click="increment">点击</button>

    五、demo实例

    demo下载地址:https://github.com/ccyinghua/vuex-demo

    1、简易vuex

    main.js

    import store from './store.js'
    
    //挂到Vue实例身上
    new Vue({
        store,
        el: '#app',
            render: h => h(App)
    })

    App.vue

    import {mapGetters,mapActions} from 'vuex'       
    
    export default{
            computed:mapGetters([  
                'count',
                'getOdd'
            ]),
            methods:mapActions([
                'increment',
                'decrement',
                'clickOdd',
                'clickAsync'
            ])
    }

    //store.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex);
    
    var state = {
        count:10
    }
    
    const mutations = {
        increment(state){       //事件;处理状态(数据)变化;  
            state.count++;
        },
        decrement(state){
            state.count--;
        }
    }
    
    const actions = {
            increment: ({          // 提交mutations
                    commit
            }) => {
                    commit('increment')
            },
            decrement: ({
                    commit
            }) => {
                    commit('decrement')
            },
            clickOdd: ({
                    commit,
                    state
            }) => {
                    if(state.count % 2 == 0){
                        commit('increment')
                    }
            },
            clickAsync: ({
                    commit
            }) => {
                    new Promise((resolve) => {
                        setTimeout(function(){
                            commit('increment');
                            resolve();
                        },1000)
                    })
            }
    }
    
    const getters = {
        count(state){
            return state.count;
        },
        getOdd(state){
            return state.count % 2 == 0 ? '偶数' : '奇数';
        }
    }
    
    //需要导出Store对象
    export default new Vuex.Store({
            state,
            mutations,
            actions,
            getters
    })

    2、复杂vuex

    main.js

    import store from './store/'
    
    //挂到Vue实例身上
    new Vue({
        store,
        el: '#app',
        render: h => h(App)
    })

    App.vue

    import {mapGetters,mapActions} from 'vuex'
    
    export default{
        computed:mapGetters([
            'count',
            'getOdd'
        ]),
        methods:mapActions([
            'increment',
            'decrement',
            'clickOdd',
            'clickAsync'
        ])
    }

    store文件夹--index.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex);
    
    import mutations from './mutations'
    import actions from './actions'
    
    //需要导出Store对象
    export default new Vuex.Store({
        modules:{
            mutations
        },
        actions
    })

    store文件夹-types.js

    // 使用常量替代 Mutation 事件类型,详见官网
    export const INCREMENT = 'INCREMENT';
    
    export const DECREMENT = 'DECREMENT';

    store文件夹-getters.js

    export default{
        count: (state) => {
            return state.count;
        },
        getOdd: (state) => {
            return state.count % 2 == 0 ? '偶数' : '奇数'
        }
    }

    store文件夹-mutations.js

    import {
        INCREMENT,
        DECREMENT
    } from './types'
    import getters from './getters'
    
    const state = {
        count:20
    }
    
    const mutations = {
        [INCREMENT](state){
            state.count++;
        },
        [DECREMENT](state){
            state.count--;
        }
    }
    
    export default{
        state,
        mutations,
        getters
    }

    store文件夹-actions.js

    import * as types from './types'
    
    export default{
        increment: ({
            commit
        }) => {
            commit(types.INCREMENT)
        },
        decrement: ({
            commit
        }) => {
            commit(types.DECREMENT)
        },
        clickOdd: ({
            commit,
            state
        }) => {
            if(state.mutations.count % 2 == 0){
                commit(types.INCREMENT)
            }
        },
        clickAsync: ({
            commit
        }) => {
            new Promise((resolve) => {
                setTimeout(function(){
                    commit(types.INCREMENT);
                },1000)
            })
        }
    }
  • 相关阅读:
    虚拟机VirtualBox 共享挂载问题:mount: /mnt/xxx: wrong fs type, bad option, bad superblock on xxx
    git 设置和取消代理
    (转载)数据库连接池到底应该设多大?这篇文章可能会颠覆你的认知
    关于golang中IO相关的Buffer类浅析
    (转)golang获取当前时间、时间戳和时间字符串及它们之间的相互转换
    FFmpeg常用命令
    go cmd nohup 的坑
    Nginx配置详解(转)
    记录一次go性能调试的过程
    github徽标引入
  • 原文地址:https://www.cnblogs.com/ccyinghua/p/7865804.html
Copyright © 2011-2022 走看看