zoukankan      html  css  js  c++  java
  • Vue状态(视图共享)管理:Vuex

    设想一下,如果不用Vuex,我们应该如何在页面各组件之间传值?通过props、$emit在父子组件之间来回穿梭传值?抑或通过bus在组件之间共享值?无论哪种方式,都是极其麻烦或者可读性非常差的。而Vuex的引入很好的解决了这个问题,它把一些共享的属性(状态)集中的管理起来,使得你只需要关注Vuex中定义的state就可以了,state的变化会自动响应到引用了它的视图(页面组件),Vuex很好的解决了以下两个问题:
    1、多个视图依赖于同一状态。
    2、来自不同视图的行为需要变更同一状态。

    一个简单的Vuex的示例如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    import Vue from 'vue'
    import Vuex from 'vuex'

    Vue.use(Vuex)

    export default new Vuex.Store({
    state(){
    return {
    count: 0,
    todos: [
    { id: 1, text: 'todo1', done: true },
    { id: 2, text: 'todo2', done: false }
    ]
    }
    },
    getters: {
    doneTodos: state => {
    return state.todos.filter(todo => todo.done)
    },
    doneTodosCount: (state, getters) => {
    return getters.doneTodos.length;
    },
    getTodoById: (state) => (id) => {
    return state.todos.find(todo => todo.id === id)
    }
    },
    mutations: {
    increment (state) {
    state.count++;
    }
    },
    actions: {
    },
    modules: {
    }
    })

    1、Vuex的核心

    Vuex的核心部分包括:State、Getter、Mutation、Action、Module

    • State:vuex中的数据源,我们需要保存的数据就保存在这里,可以在页面通过 this.$store.state访问到它。
    • Getter:Getter相当于vue中的computed计算属性,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
    • Mutation:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数。提交mutation必须是同步的方式(不可以异步)。
    • Action:Action 类似于 mutation,不同在于:
      a、Action 提交的是 mutation,而不是直接变更状态。
      b、Action 可以包含任意异步操作。
      Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。Action 通过 store.dispatch 方法触发,如:
      1
      store.dispatch('increment')

    Action不受同步的约束!我们可以在 action 内部执行异步操作:

    1
    2
    3
    4
    5
    6
    7
    actions: {
    incrementAsync ({ commit }) {
    setTimeout(() => {
    commit('increment')
    }, 1000)
    }
    }

    注:建议最好所有的Mutation操作都用action分发,这样如果业务发生变更(需要由同步变成异步的操作方式),你只需要更改store中的相关action定义就可以了,而不需要去修改引用它的业务代码。

    • Module:Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。分模块后更便于维护store,如果所有状态都放在一个store中会使得这个store过于臃肿,且不易于维护。

    2、在视图(页面组件)中访问State、Getter、Mutation、Action

    在页面视图中,我们可以分别使用this.$store.state、this.$store.getters访问State和Getter,使用this.$store.commit(‘xxx’) 提交 mutation,使用this.$store.dispatch(‘xxx’) 分发 action。但这样使用并不规范也不方便,vuex提供了相应的辅助函数:mapState、mapGetters、mapMutations、mapActions用来分别访问它们。示例如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'

    export default {
    // ...
    computed:{
    ...mapState({
    // 箭头函数可使代码更简练
    count: state => state.count,

    // 传字符串参数 'count' 等同于 `state => state.count`
    countAlias: 'count',

    // 为了能够使用 `this` 获取局部状态,必须使用常规函数
    countPlusLocalState (state) {
    return state.count + this.localCount
    }
    }),
    ...mapGetters([
    'doneTodosCount',
    'anotherGetter',
    // ...
    ])
    },
    methods: {
    ...mapMutations([
    'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`

    // `mapMutations` 也支持载荷:
    'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
    ]),
    ...mapMutations({
    add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
    }),
    ...mapActions([
    'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`

    // `mapActions` 也支持载荷:
    'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
    ]),
    ...mapActions({
    add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
    })
    }
    }

    3、示例demo

    一个简单的Vuex的示例Demo,请访问https://github.com/johnnynie/vue-demos/tree/master/vuex-demos/demo1

  • 相关阅读:
    IIS配置和发布网站
    单点登录的理论原理(一)
    Tomcat乱码或异常
    浅谈Tomcat 、Apache、 Nginx的区别及优缺点
    KETTLE数据互交
    Centos7防火墙配置
    【linux】查看某个进程PID对应的文件句柄数量,查看某个进程当前使用的文件句柄数量
    this license XXXXXX has been cancelled
    Ubuntu16.04安装Redis
    redis的 rdb 和 aof 持久化的区别
  • 原文地址:https://www.cnblogs.com/niejunchan/p/12866430.html
Copyright © 2011-2022 走看看