vuex及组件通讯

89 阅读1分钟

vuex的使用

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式库

vue中data中的数据是一个响应式的数据,只能在当前组件使用。当然如果在其它组件使用时,可以通过propsemitprovideinject等进行配合使用。vuex相当于一个全局的数据库,每个组件都可以更新里面的状态。前者在组件间的联系十分紧密,代码不容易维护,后者将状态全部抽离,更容易维护。这是我对vuex的理解

Vuex的重要概念:stategettermutationactionmodule.

state的使用

//vuex中
state: {
    count: 2,
},

上面代码在vuex中定义了一个state,那么在组件中如何使用这个count呢?

computed:{
    count(){
      return this.$store.state.count
    }
}

在上述代码中我在computed中使用了计算属性count,获取storecount的值,这样就可以在页面上进行使用了。

当在computed中使用了很多的属性,代码就会重复,如下代码1.1:

//vuex
state: {
    count: 2,
    firstName: 'feng',
    lastName: "wang",
 },
//组件中使用,当然也可以通过{{$store.state.count}}直接在模板中获取
count(){
    return this.$store.state.count
},
firstName(){
    return this.$store.state.firstName
},
lastName(){
   return this.$store.state.lastName
}

vuex中提供了mapState这个辅助函数,帮助我们生成计算属性

computed:mapState({
    count:state=>state.count,
    //下面这种写法相当于firstName:state=>state.firstName,
    firstName:'firstName',
    //使用this必须使用普通函数
    lastName(state){
     return state.firstName + this.string
    }
})

当计算属性的名称与state中名称相同时,可以传递一个字符串数组

//1.1简化
computed:mapState(['count','firstName','lastName'])

但是问题来了,组件中要使用computed时,怎么办呢?

//mapState被调用时返回的是一个对象,通过...(扩展运算符)就可以解决这个问题

//数组版简单,推荐使用
computed: {
    //这里可以写组件自身的计算属性
    ...mapState(['count','firstName','lastName']),
},
//对象的形式
computed: {
    ...mapState({
      count:"count",
      fistName:'firstName',
      lastName:"lastName"
    }),
},

总结

state:是用来管理所有用到的组件中的状态的 mapState:用来减少代码的重复,简化操作

getter的概念和使用

getter类似于一个vue中的计算属性,主要用来解决组件间的属性共用。如组件A、B中都希望使用doneTodosCount来对对列表进行过滤并计数,可以在A、B组件定义一个computed来计算,但是A、B组件中都要定义,getter很好的解决了这个问题

state: {
     todos: [
        { id: 1, text: '...', done: true },
        { id: 2, text: '...', done: false }
     ]
},
getters: {
    //getter接收第一个参数为state,第二个参数为getter
    doneTodos: (state) => state.todos.filter(item => item.done).length
}

//在组件中使用
computed: {
    doneTodes(){
         return this.$store.getters.doneTodos
    }
}
//模板中可以使用{{doneTodes}}
//当然也可以直接在模板中获取{{$store.getters.doneTodos}}

通过方法来传递参数,这种情况下getter并不会由缓存

getTodosById: (state) => (id) => {
     return state.todos.find(item => item.id === id)
}
//组件中使用
computed:{
    getTodosById(){
      return this.$store.getters.getTodosById(2)
    },
}

mapGetters的使用

import { mapGetters } from 'vuex'
computed:{
    ...mapGetters(['getTodosById']),
    //使用对象的形式重命名
    //...mapGetters({
      //done:'doneTodos'
    //}),
}

mutations

mutations提交必须是同步函数

mutations: {
    //更改state中的值
    increment(state,payLoad) {
         state.count += payLoad.count
    }
},

组件中使用

//传递一个参数{count:10}
$store.commit('increment',{count:10})
//对象风格提交,相当于上面那种方式
$store.commit({type:'increment',count:10}

使用mapMutations传递参数

methods:{
    ...mapMutations(['increment'])
}
//template中使用,传递参数
<button @click="increment({count:10})">n+1</button>

action的使用

1.action是通过mutation更改state中的值 2.action可以进行异步任务

//使用
actions: {
    increment({ commit }, payLoad) {
         commit('increment', payLoad)
    }
},
//组件中触发
$store.dispatch('increment',{count:10})

使用mapActions

actions: {
        increment({ commit }, payLoad) {
        //传递参数
            commit('increment', payLoad)
        }
},
import {mapActions} from "vuex"
methods:{
    ...mapActions(['increment'])
}
//template中
increment({count:10})