Vue.js vuex

1.前言

  • Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,它解决了vue中不同组件之间状态共享的问题。
  • 通俗的说,它就是一个带响应式的全局变量管理,它数据的改变会触发相关页面/组件的更新,这是普通全局变量做不到的

2.vuex的安装及配置

  • npm安装vuex
npm install vuex --save
  • 编写vuex模块
//src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'

// Vue.js 插件
Vue.use(Vuex)

const state = {
    count: 0
}

const getters = {
    
}
//Vuex中store数据改变的唯一方法就是mutation
const mutations = {
    
}

// mutations的再封装,mutations本身只负责state的数据修改,其余逻辑放在actions中,在通过它进行一系列逻辑处理之后再调用mutations
const actions = {
    
}

export default new Vuex.Store({
    state,// 状态对象,相当于data
    getters,// 包含多个getter计算属性函数的对象
    mutations, // mutations 里面装着改变数据的方法集合,处理数据逻辑的方法全部放在 mutations 里,使数据和视图分离。
    actions // action 可以包含任意异步操作,例如发送ajax请求
})
  • 入口文件中引入vuex模块
// main.js
import Vue from 'vue'
import App from './App'
import router from './router'

import store from './store'


Vue.config.productionTip = false

new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>',
  store
})

3.state和getters的定义

  • state的值为一个对象,里面的键值对就是一个个状态(数据)
const state = {
    count: 0,
    msg:''
}
  • getters类似于vue中的计算属性,他是一个对象,里面可以定义多个方法
  • 每个方法需要返回一个值,这个值就是这个属性的值
  • 每个方法存在2个参数,分别为:state和getters
const getters = {
    OddorEven (state,getters) {
        // vuex已经为其传递了state和getters这个参数

        //返回的值就是这个属性的值
        return state.count%2===0 ? '偶数':'奇数'
    }
}

4.组件中读取state和getters

  • 可以直接在组件的HTML模版中直接绑定数据(不推荐,uni-app中这种写法不支持)
<p>{{$store.state.count}} </p>
<p>{{$store.getters.OddorEven}}</p>
  • 在组件的js中,通过this.$store来读取state和getters
created(){
    console.log(this.$store.state.count)
    console.log(this.$store.getters.OddorEven)
}
  • 推荐通过计算属性来同步state和getters到组件中,再绑定到HTML模版
<p>{{count}} </p>
<p>{{OddorEven}}</p>
computed:{
    count(){
         return this.$store.state.count
    },
    OddorEven(){
         return this.$store.getters.OddorEven
    }
}
  • 不可对state和getters进行赋值
this.$store.state.count = 100 //不支持

5.mutations的定义和调用

  • vuex中的state数据涉及多个组件,为了方便管理这些公共数据,它希望通过方法调用的形式来修改这些数据,而不是直接赋值修改(毕竟方法名比直接赋值更加直观,更能表现代码意图),所以就有了mutations
  • mutations就是这些方法的集合,里面可定义多个方法,专门修改state的数值,参数一固定为state,参数二是方法调用时的传参,如果要传递多个参数,可将其封装成一个对象
//定义mutations
const mutations = {
    INCREMENT (state) {
        state.count++
    },
    CHANGEMSG(state,val){
        // 函数的第一个参数永远是state,便于读取state
        // 自定义传递的参数是第二个,可以省略
        state.msg = val
    }
}
  • vue组件中通过$store.commit()方法来调用mutations中定义的方法
methods: {
    test() {
        // 触发vuex里面mutations的相关方法 'INCREMENT'
        this.$store.commit('INCREMENT')
        // 传递参数
        this.$store.commit('CHANGEMSG','msg改变了')
    }
}

6.actions的定义和调用

  • 前面的mutations中,它只负责单纯的修改state数据,而我们修改数据的时候直接往往还要进行其他逻辑处理,所以就有了actions
  • actions是众多方法的集合,通过它进行逻辑处理后,再调用mutations中的方法修改state的数据
  • actions中的方法有参数一是固定的{commit,state},自定义参数为参数二
const actions = {
    incrementFn ({commit,state}) {
        if(state.count < 100){
            commit('INCREMENT')
        }
    },
    changeMsgFn ({commit,state},newMsg){
        // 参数一是固定的
        // 第二个参数为传递的参数
        setTimeout(() => {
            commit('CHANGEMSG',newMsg)
        },1000)
    }
}
  • vue中通过$store.dispatch()方法来调用actions中的方法
//vue组件
methods: {
    test() {
        // 触发vuex里面actions的相关方法
        this.$store.dispatch('incrementFn')
        //传递参数
        this.$store.dispatch('changeMsgFn','msg改变了')
    }
}

7.代码优化 mapState/mapGetters/mapMutations/mapActions

  • 一般情况下,可以使用组件的计算属性同步state数据和getters数据,使用methods中的方法来调用mutationsactions中的方法
methods: {
    //定义一个调用mutations的方法
    incrementFn() {
        this.$store.commit('INCREMENT')
    },
    //定义一个调用actions的方法
    changeMsgFn() {
        this.$store.dispatch('changeMsgFn')
    }
},
computed:{
    count(){
         return this.$store.state.count
    },
    OddorEven(){
         return this.$store.getters.OddorEven
    }
}
  • vuex提供一种简写的方式来调用vuex中的state/getters/mutations/actions
    (1)引入mapState,mapGetters,mapMutations,mapActions
import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'

// mapState(['count'])返回一个对象 count:function(){}
// 相当于获取store.state.count的值

(2)使用ES6扩展运算符将这个对象的键值对插入到vue计算属性和methods中

//使用数组传参,需要vue和actions的名称一致
computed: {
    ...mapState(['count']),
    ...mapGetters(['OddorEven'])
},
methods: {
    ...mapActions(['increment']),
    ...mapActions(['incrementIfOdd']),
    ...mapActions(['incrementAsync'])
}

(3)也可以使用对象形式传参,这种形式可以自定义组件中的方法名称
语法: ...mapGetters({vue名称:'action名称'})

8.配合v-model使用

涉及双向数据绑定要使用vue的计算属性设置get方法和set方法
(1)在get方法中使用$store.state读取状态数据
(2)在set方法中使用$store.commit()修改状态数据

// 组件模版
<input type="text" v-model="msg"></input>
// vue的计算属性
computed: {
    msg: {
        get(){
            return this.$store.state.msg
        },
        set(val){
            this.$store.commit('changeMsg',val)
        }
    }
}
// store模块
const state = {
    msg:''
}
const mutations = {
    CHANGEMSG(state,val){
        state.msg = val
    }
}
posted @ 2019-11-12 21:54  ---空白---  阅读(225)  评论(0编辑  收藏  举报