Vuex知识整理

Vuex知识整理

  • state 用来数据共享数据存储
  • mutation 用来注册改变数据状态
  • getters 用来对共享数据进行过滤操作
  • action 解决异步改变共享数据
vuex是什么?

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

为什么使用Vuex?

当你打算开发大型单页应用(SPA),会出现多个视图组件依赖同一个状态,来自不同视图的行为需要变更同一个状态。

遇到以上情况时候,你就应该考虑使用Vuex了,它能把组件的共享状态抽取出来,当做一个全局单例模式进行管理。这样不管你在何处改变状态,都会通知使用该状态的组件做出相应修改。

下面讲解如何使用Vuex。

1、在vuex文件夹里创建5个js文件
  • index.js
  • mutations.js
  • state.js
  • getters.js
  • actions.js
2、分别把这四个特性放入index.js中进行store的实列化
// index.js
import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import getters from './getters'
import mutations from './mutations'
import actions from './actions'

Vue.use(Vuex)

export default new Vuex.Store({
  state,
  mutations,
  actions,
  getters
})
3、再把实列化的store引入到main.js中,也可以同时把store注册到每一个组件中
// main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')
4、state的用法
  • 我们可以在state.js中先声明一数据值
// state.js
export default{
    title : "首页"
}
  • 那我们如何在首页中拿到这个title值呢
    • 在项目中的vue页面中我们可以这么取到state里的值
// 如在views/Home.vue
<template>
  <div class="Home">123</div>
</template>

<script>
export default {
  name: 'Home',
  created () {
    this.getInfo()
  },
  methods: {
    getInfo () {
      console.log(this.$store.state.title) // 首页
      console.log(this.title) // 首页
    }
  },
  computed: {
    title () {
      return this.$store.state.title
    }
  }
}
</script>
5、matutions的用法

如果我们要改变顶层的共享数据,我们应该要用matutions来进行改变

// matutions.js
export default{
    setTitle (state, value) {
       state.title = value
    }
}

然后我们在Home.vue里改变

  • this.$store.commit()方法
// Home.vue
<template>
  <div class="Home">123</div>
</template>

<script>
export default {
  name: 'Home',
  created () {
    this.getInfo()
  },
  methods: {
    getInfo () {
      console.log(this.$store.state.title) // 首页
      console.log(this.title) // 首页
      this.$store.commit('setTitle', 'Hello')
      console.log(this.$store.state.title) // Hello
    }
  },
  computed: {
    title () {
      return this.$store.state.title
    }
  }
}
</script>
6、getters的用法

getter就是对state里的数据进行一些过滤,改造等等

比方说State里有一些这样的数据

// state.js
export default{
    title : "首页",
    people : [
      {name : '小明',age:21},
      {name : '小红',age:10},
      {name : '小军',age:30},
      {name : '小黄',age:40},
      {name : '小紫',age:50},
      {name : '小康',age:30},
      {name : '小娜',age:80}
    ]

如果我们定义这些数据,然后我们要从,这些数据中筛选出年纪大于30的人,再进行返回,我们就可以用到getter,这里的getter的意思就是对vuex顶层数据进行过滤,而不改动state里原本的数据

// getters.js
export default{
    selectPeople: (state) =>{
        return state.people.filter(item=>{
            return item.age>30
        })
    }
}

好,我们如何应用呢,我们在组件中里只要写入

// Home.vue
<template>
  <div class="hello">123</div>
</template>

<script>
export default {
  name: 'HelloWorld',
  created () {
    this.getInfo()
  },
  methods: {
    getInfo () {
      console.log(this.$store.getters.selectPeople) //筛选出了小黄、小紫、小娜
    }
  }
}
</script>
7、actions的用法

actions是用来解决异步流程来改变state数据的,直接在matution里面进行写进是改变不了的,因为matution是直接进行同步操作的
只有通过action->mutations->states,这个流程进行操作 才能改变异步操作进行更改的数据

export default {
  setTitleAsync (context, value) {
      setTimeout(()=>{
        context.commit('setTitle',value)
      },3000)
  }
}

第一个参数就是上下文,context是一个store对象,你也可以用解构的方式写出来,第二个参数还是我们要写入的接收到的参数,来改变触发mutations事件,再通过mutation来改变state

然后我们就在组件里这么调用就可以了

<template>
  <div class="hello">123</div>
</template>

<script>
export default {
  name: 'HelloWorld',
  created () {
    this.getInfo()
  },
  methods: {
    getInfo () {
      this.$store.dispatch('setTitleAsync', '异步更改数据')
    }
  }
}
</script>
8、辅助函数mapState , mapMutations , mapActions , mapGetters
调用 方法 辅助函数
state this.$store.state.xxx mapState
getters this.$store.getters.xxx mapGetters
mutations this.$store.commit('xxx') mapMutations
actions this.$store.dispatch('xxx') mapActions

==注意== mapState和mapGetter的使用只能在computed计算属性中, mapMutations和mapActions使用的时候只能在methods中调用否则报错

如何实际使用辅助函数?

// Hello.vue
<template>
  <div class="hello">123</div>
</template>

<script>
import { mapState , mapMutations, mapActions, mapGetters  } from 'vuex';
export default {
  name: 'HelloWorld',
  created () {
    this.getInfo()
    this.setInfo()
    this.setInfoAsync()
  },
  methods: {
    // mapMutations和mapActions使用的时候只能在methods中调用
    getInfo () {
      console.log(this.title) // 首页
      console.log(this.people) 
      console.log(this.selectPeople)             
    },

    ...mapMutations(['setTitle']),  // 第一种 推荐
    // ...mapMutations({addnum:'addNum'}) // 第二种
    setInfo () {
      this.setTitle('hello')
      console.log(this.title) // hello
      //mapMutations就等于下面的这个       
      //this.$store.commit('setTitle', 'hello')
    },
    
    ...mapActions(['setTitleAsync']), // 第一种 推荐
    // ...mapActions({  // 第二种
    //   setTitleAsync:'setTitleAsync'
    // })
    setInfoAsync () {
      this.setTitleAsync('异步更改为hello')
      //mapActions就等于下面的这个      
      //this.$store.dispatch('setTitleAsync', '异步更改为hello')      
    }
  },
  computed:{
    //  mapState和mapGetter的使用只能在computed计算属性中
    
    ...mapState(['title', 'people']),  //更简洁的写法 推荐
    // ...mapState({
    //   title:'title' // 第一种写法
    //   // title:(state) => state.title // 第二种写法
    // }),
    ...mapGetters(['selectPeople'])  //更简洁的写法 推荐
    // ...mapGetters({
    //   selectPeople:'selectPeople'
    // })
  }
}
</script>

9、辅助函数总结

vuex中的 mapState , mapMutations , mapActions , mapGetters 辅助函数看上面的例子其实差不多,当项目场景中我们需要大量的调用state中的值和触发多个actions的时候,我们还得写大量重复的代码,这时候辅助函数的作用就体现出来了,其实就是vuex的一个语法糖,使代码更简洁更优雅。