Vue的Vuex的使用

一、Vuex是什么?

  1:Vuex是一个专为vue.js应用程序开发的状态管理模式,核心就是一个store仓库,采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。基本思想:通过定义和隔离状态管理的各种概念并通过强制维持视图和状态间的独立性,我们的代码将会变得更结构化且易维护;

  2:状态管理模式:state,驱动应用的数据源;view,以声明方式将state映射到视图上;actions,响应在view上的用户输入导致的变化;

  3:单向数据流:单向数据流容易被破坏,在多个组件共享状态时:像多个视图依赖同一个状态或者来自不同视图的行为需要变更同一状态;

  4:何时使用vuex:如果需要构建一个中大型单页面应用;

二、Vuex和单纯全局对象不同点:

  1:Vuex的状态存储是响应式的。当Vue组件从store中读取状态的时候,若store中的状态发生变化,那么相应的组件也会相应的得到高效的更新;

  2:不能直接更改state中的状态。改变store中的状态唯一的途径是显示的提交(commit)mutation。这样使得我们可以方便的跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好的了解我们的应用;

  3:关于:store

// 创建一个store
const store = new Vue.Store({
    state: { count: 0 },
    getters: {},
    mutations: {
        increment(state){ state.count++ }
    },
    actions: {}
})

// 在Vue组件中访问this.$store property,以及通过this.store.commit方法触发状态变更
this.$store.state.count  // 0
this.$store.commit('increment') // count 1

//Vuex提供了一个从根组件向所有子组件,以store选项的方式注入该store的机制;
new Vue({
    el: '#app',
    store // 把store对象提供给“store”选项,可以把store的实例注入到所有的子组件 需要调用Vue.use(Vuex)
})

// 由于store中的状态是响应式的,在组件中调用store中的状态简单到仅需要在计算属性中返回即可。触发变化也仅仅是在组件的methods中提交mutation

三、核心概念 state、getters、mutations、actions、module

  1:state:Vuex使用的单一状态树,则state作为唯一数据源;由于Vuex的状态存储是响应式的,从store实例中读取状态最简单的方法就是在计算属性中返回某个状态;

// a组件
computed: {
    count() {
        return this.$store.state.count // 当依赖值变化的时候,都会重新求取计算属性,并且触发更新相关联的DOM
    }
}

  2:mapState辅助函数:当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余;

// mapState辅助函数使用    // 在单独构建的组件中辅助函数为 Vuex.mapState
import {   mapState  } from 'vuex'
// mapState返回的是一个对象,我们利用对象展开运算符将它和局部的计算属性混合即可
computed: { ...mapState({ ...... }) }

  3:getter:类似于计算属性,可以对state中的数据加工后传递给组件;有时候需要从store中的state中派生出一些状态;

    getters中的方法有两个默认参数:state,当前vuex对象中的状态对象;getters,当前getters对象,用于将getters下的其他getter拿来用;

   就像计算属性一样,getter的返回值会根据它的依赖被缓存起来,且只有当它的依赖发生了改变才会被重新计算;

// getter接收state作为第一个参数
const store = new Vue.Store({
    state: {
          todos: [
          { id: 1, done: true },
          { id: 2, done: false }
         ]
    },
    getters: {
          doneTodos: state => {
               return state.todos.filter(todo => todo.done)
          }
    }
})

    #通过属性访问:

// getter会暴露this.$store.getter对象,可以通过属性的方式访问这些值
this.$store.getter.doneTodos // { id:1, done: true }
// getter接收的第二个参数:getters
getters: {
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}
this.$store.getter.doneTodosCount // -> 1
#getter在通过属性访问时作为Vue的响应式系统的一部分缓存其中的

    #通过方法访问:

// 也可以通过让getter返回一个函数,来实现getter传参
getters: {
    getTodoById:  (state) => (id) => {
        return state.todos.find(todo => todo.id === id)
    }
}

this.$store.getters.getTodoById(2)  // -> { id: 2, done: false }

#getter在通过方法访问时,每次都会进去调用,而不会缓存结果

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

import { mapGetters } from 'vuex'

computed: {
    // 使用对象展开运算符getter混入computed对象中
     ...mapGetters(['doneTodoCount', '', ...])
}
// 如果想将一个getter属性取别名,使用对象形式
...mapGetters({ doneCount: 'doneTodoCount' })

  5:mutations:更改Vuex的store中的状态的唯一方法是提交mutation。每个mutation都有一个字符串类型的事件类型(type)和一个回调函数(handler),这个回调函数是我们实际进行状态更改的地方,接收state作为第一个参数;

const store = new Vue.Store({
    state: { count: 1 },
    mutations: {
         // state和payload两个参数:payload载荷
         increment(state, payload) {
             state.count += payload
             // state.count += payload.amount
        }
    }
})
// 组件触发回调
this.$store.commit('increment', 10)
// 载荷一般为对象
this.$store.commit('increment', { amount: 10 })

// 对象风格的提交方式:提交mutation的另一种方式是直接包含type属性的对象
store.commit({ type: 'increment', amount: 10 })

    #Mutation需遵守Vue的响应规则

      ~:最好提前在store中初始化好所有的所需属性;

      ~:当需要在对象上添加新属性时,你应该 使用Vue.set(obj, 'newProp', 123) 或 以新对象替换老对象:state.obj = { ...state.obj, newProp: 123  }

    #Mutation必须是同步函数

    #在组件中提交Mutation

import { mapMutations } from 'vuex'

methods: {
    ...mapMutations([
        'increment',  // 将this.increment() 映射为 this.$store.commit('increment')
        'incrementBy', // 将 this.incrementBy(amount)映射为this.$store.commit('incrementBy', amount)
    ])
    ...mapMutations({
        add: 'increment' // 将this.add()映射为this.$store.commit('increment')
    })
}

  6:action:提交的是mutation而不是直接变更状态;action可以包含任意异步操作;

  action函数接受一个与store实例具有相同方法和属性的context对象;因此可以调用context.commit提交一个mutation或者通过context.state和context.getters来获取state和getters;

  action是通过this.$store.dispatch触发;action支持同样的载荷方式和对象方式进行分发;使用方法同mutations

  this.$store.dispatch可以处理被触发的action的处理函数返回的promise,并且this.$store.dispatch仍旧返回promise

actions: {
  actionA ({ commit }) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        commit('someMutation')
        resolve()
      }, 1000)
    })
  }
}

this.store.dispatch('actionA').then(() => {
  // ...
})
原文地址:https://www.cnblogs.com/xsk-walter/p/12765253.html