vuex的五个属性state、getters,、mutations,、actions、modules

数据状态管理器(vuex)

  • 作用:管理数据和状态
  • Vuex有五个核心概念:
    state, getters, mutations, actions, modules
  • 使用(和 vue-router 一样)
  1. 下载包 vuex npm i vuex
  2. 引入包 vuex
  3. Vue 实例上注册 Vue.use(vuex)
  4. 创造一个仓库实例 const store = new Vuex.Store()
  5. 把创造的 vuex 实例挂载到 Vue 实例上 new Vue({store})

首先:
在src下新建文件夹store,在store下新建index.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
		
const store = new Vuex.Store({
	state: {}
})
		
export default store

其次:
在main.js中引入store下的index.js

import vuex from './store'
		
new Vue({
	// 挂载元素
	el: '#app',
	// 把对应的路由实例注册到vue实例中
	router,
	// 把对应的vuex实例挂载 到vue实例中
	vuex,
	// 组件 在vue里加载对应的app组件
	components: { App },
	// 对应的模块,就是对应的html的内容
	template: '<App/>'
})
  • state (状态) - 专门用来存储我们的数据
    • 在 new Vuex.Store({
      state: {}
      })
    • 在组件中获取的时候使用 this.$store.state.数据名称
    • 在组件中尽量使用 computed 来获取,因为可以随着改变而改变
// 创建一个 Counter 组件
const Counter = {
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
      return this.$store.state.count
    }
  }
}
  • mutation (改变) - 在 vuex 中专门用来修改 state 中的数据

    • 当你想改变 state中的数据的时候
    • mutation 中去定义一个 方法,用这个方法的第一个参数 state 去修改
    • 在组件中想办法调用 mutation 中改变state的方法
    • 在组件中使用 commit 去调用 mutation 中的方法
      // store.js
      new Vuex.Store({
        state: {
          data: 'abc'
        },
        mutations: {
          changeData (state) {
            state.data = 'gaibian'
          }
        }
      })
    
      // 组件中
      // 在执行 js 代码的位置(你想让数据发生改变的位置)
      // 第一个参数是方法名称
      // 第二个参数是携带过去的数据
      this.$store.commit('changeData')
    

    示例: 在组件中改变state中的数据,传多个值

    // store.js文件
    const store = new Vuex.Store({
      state: {
        data: '我是 vuex 中 state 里面的数据'
      },
      mutations: {
        changeData (state, [type, str]) {
          state.data = type
          console.log(type)
          console.log(str)
        }
      }
      // mutation 中的每一个成员都是一个方法
     // 这个方法就是专门用来修改 state 中的数据的
    // 接收两个参数
    
    // changeData中的参数
    // state - 就代表着 store 中的那个 state 对象
    // 第二个参数就是专门接收 commit 的时候带过来的参数
    // 如果是一个参数,直接接收就行
    // 如果是多个使用数组的形式接受
    })
    
    // comOne.vue
    <template>
      <div>
        {{ msg }}
        <p>{{ data }}</p>
        <button @click="changeData">改变 state 中的数据</button>
        <input type="text" v-model="msg">
      </div>
    </template>
    
    <script>
    export default {
      name: 'comOne',
      created () {
        // console.log(this.$store)
      },
      data () {
        return {
          msg: '我是 comOne 组件'
          // data: this.$store.state.data  // 需求: 当 this.$store.state.data 改变的时候我能重新获取其值
        }
      },
      computed: {
        // 获取每一个 state 中的数据需要借助 computed 来获取
        // 因为 computed 可以在数据发生改变的时候重新能获取
        data () {
          return this.$store.state.data
        }
      },
      methods: {
        changeData () {
          // 可以修改 state 中的数据,但是你仅仅只是可以修改数据,不能修改状态
          // this.$store.state.data = '我被改变了'
    
          // 那么就需要让 $store 里面的 mutation 中的 changeData 方法执行一下
          // 我们有一个 commit 属性,专门用来触发 mutation 中的方法使用的
          // 合理的修改 state 中的数据的方式
          // commit 第一个参数,是 mutation 中 的方法名称
          // commit 第二个参数,是在调用 mutation 中的方法的时候传的参数(以数组的形式)
          this.$store.commit('changeData', [this.msg, 'abc'])
          // console.log(this.$store)
        }
      }
    }
    </script>
    
    
  • action (行为) - 在 vuex 里面专门用来异步的改变数据的方式,可以包含任意异步操作

    • 不是直接去调用 mutation 中的 方法
    • 而是使用了 action 中的方法去提交 mutation 中的方法,从而变更状态
    • 借助了 dispatch
    • dispatch('action 中的方法', 调用的时候携带的参数)
// store.js
const store = new Vuex.Store({
  state: {
    data: '我是 vuex 中 state 里面的数据'
  },
  mutations: {
    changeData (state, type) {
      // mutations 中的方法,记录状态这个过程是同步的
      // 先记录状态,然后再执行 定时器
      // 所以 记录的状态是上一次的,所以 mutations不可以异步改变数据
      // 并不是 改变的 数据不对 ;而是 状态不是 最新的,永远是 上一条的状态
      // setTimeout(() => {
      //   state.data = type
      // }, 0)

      state.data = type
    }
  },
  actions: {
    // actions 里面接收的也是方法
    // 这里面的方法专门用来去提交 mutations 中的方法
    asyncChangeData (store, type) {
      // store 就是整个仓库
      // 你不需要等着它执行完,过了两秒就会自动执行,并且状态是最新的
      setTimeout(() => {
        store.commit('changeData', type)
      },  2000)
      
    }
  }
})

// comOne.vue
data () {
    return {
      msg: '我是 comOne 组件'
    }
  },
  computed: {
    data () {
      return this.$store.state.data
    }
  },
  methods: {
    changeData () {
      // 当我们想异步的改变数据的时候,不能使用commit 去提交 mutations中的 方法
      // 因为不是改变不了数据,而是状态不能记录成最新的 
      this.$store.commit('changeData', this.msg)
      // console.log(this.$store)

	  this.$store.dispatch('asyncChangeData', this.msg)
      // 想异步的改变
      // 做法:不是异步的去改变数据,而是异步的去提交改变数据的方式
      // 需求:一秒钟以后改变数据
      //   不是一秒钟以后再改变数据
      //   而是一秒钟以后 去 提交改变数据的 行为
      // 我们使用一个  action
      /*
        想异步去改变 state 中的数据的时候,只要让actions 中 的 asyncChangeData 执行
        asyncChangeData 就会去commit mutations中的 changeData
        changeData 就会去改变 state 中的数据
        dispatch - 派遣,急派
          - 专门用来调用 actions 中的方法
      */
     /*
        this.$store.dispatch('asyncChangeData', this.msg)
        这行代码所走的行程:
          使用dispatch 触发 actions 中的 asyncChangeData 方法,并将参数传入;
          asyncChangeData 方法 使用 commit 触发 mutations 中的 changeData 方法,并将 参数携带过去;
          changeData 就会去 改变 state 中的数据
          计算属性 computed 发现 state 中的 data发生改变;则会重新return出新的值
      */

    }
  }
  • getters(获取器)
  • vuex 里面的 computed计算属性,就是专门用来对输出数据进行改变
    有时候我们需要从store中的state中派生出一些状态,例如对列表进行过滤并计数
    • 在不改变原始数据的基础上让我输出的数据发生一些变化
    • 和 组件中的 computed 作用完全一样
    • 获取的方式和获取state 中的数据一样
    this.$store.state.data  // 获取 state 中的数据
    this.$store.getters.data2  // 获取 getter 中处理过的数据
    
getters: {
    // data4是所有的data的数据反转
    // 和过滤器比较像,但为什么说是vuex中的 计算属性
    // 因为当原始 数据 state 改变的时候,会重新 计算我的值;return出新的反转字符串;这是computed的属性
    data4 (state, type) {
      return state.data.split('').reverse().join('')
    }
  }


 computed: {
    data () {
      // return this.$store.state.data
      // 获取到的是反转后的字符串
      return this.$store.getters.data4
    },
 }


  • modules(模块化)

    • 可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理

    备注:
    为什么把vuex单独提出来,而不放在main.js中
    1、模块化开发
    2、main.js需要引入第三方插件,自己封装的组件之类的,东西过多
    vuex和全局对象的区别:
    1、vuex的存储是响应式的。当vue组件从store中读取状态的时候,若store中的状态发生改变,那么相应的组件也会相应地得到高效更新。
    2、你不能直接改变store中的状态。改变store中的状态的唯一途径就是提交(commit)mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
    如何在 vue 组件中获得vuex状态
    1、由于vuex的状态存储是响应式的,从store实例中读取状态最简单的方法就是在计算属性中返回某个状态

相关推荐
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页