Vue笔记_05_vuex

第五章 vuex

vuex是什么?

  1. 概念:专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式管理(读/写),也是组件间通信的方式,且适用于任意组件间通信
  2. Github地址:Vuex

什么时候用Vuex

  1. 多个组件依赖于同一状态
  2. 来自不同组件的行为需要变更同一状态

搭建vuex环境

  1. vuex的工作原理图

在这里插入图片描述

  1. 安装vuex:npm install --save vuex

  2. 创建文件:src/store/index.js

    // 引入Vue核心库
    import Vue from 'vue'
    // 引入Vuex
    import Vuex from 'vuex'
    // 应用Vuex
    Vue.use(Vuex)
    
    // 准备actions对象--响应组件中用户的动作
    const actions = {}
    //  准备mutations对象--修改state中的数据
    const mutations = {}
    // 准备state对象--保存具体的数据
    const state = {}
    
    
    // 创建并暴露store
    export default new Vuex.Store({
      actions, mutations, state
    })
    
  3. main.js中创建vm时传入store配置项

    import Vue from 'vue'
    import App from './App.vue'
    
    // 引入store
    import store from './store/index'
    
    Vue.config.productionTip = false
    
    // 创建vm的时候注册store
    new Vue({
      render: h => h(App),
      store,
    }).$mount('#app')
    
  4. 组件中读取vuex中的数据:$store.state.sum

  5. 组件中修改vuex中的数据:$store.dispatch('action中的方法名',数据)或者$store.commit('mutations中的方法名',数据)

案例

vue版本

在App.vue文件里:

<template>
  <div>
    <Count/>
  </div>
</template>

<script>
import Count from './components/Count.vue'

export default {
  name:'App',
  components:{Count}
}
</script>

<style>
  body {
    background-color: #e0e0e0;
  }
</style>

在Count.vue文件中:

<template>
  <div id="Count">
    <h1>当前求和为{{sum}}</h1>
    <!-- 用v-model绑定n的值,用number限定词来限定n的值为数字 -->
    <select v-model.number="n">
      <option :value="1">1</option>
      <option :value="2">2</option>
      <option :value="3">3</option>
    </select>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
    <button @click="incrementOdd">当前求和为奇数再加</button>
    <button @click="incrementWait">等一等再加</button>
  </div>
</template>

<script>
export default {
  name:'Count',
  data() {
    return {
      n:1, // 用户选择的数字
      sum:0 // 当前的和
    }
  },
  methods: {
    // 加法
    increment() {
      this.sum += this.n
    },

    // 减法
    decrement() {
      this.sum -= this.n
    },

    // 当sum的值为奇数的时候才加,不然就不加
    incrementOdd() {
      if (this.sum % 2) {
        this.sum += this.n
      }
    },

    // 等一等再加
    incrementWait() {
      setTimeout(()=>{
        this.sum += this.n
      }, 500)
    }
  },
}
</script>

<style scoped>
  #Count {
    margin: 0 auto;
    width: 80%;
  }

  button {
    margin-left: 5px;
  }

  button:hover,
  select:hover {
    cursor: pointer;
  }
</style>

vuex版本

在main.js文件里:

import Vue from 'vue'
import App from './App.vue'

// 引入store
import store from './store/index'

Vue.config.productionTip = false

// 创建vm的时候注册store
new Vue({
  render: h => h(App),
  store,
}).$mount('#app')

src/store/index.js里:(重点)

// 引入Vue核心库
import Vue from 'vue'
// 引入Vuex
import Vuex from 'vuex'
// 应用Vuex
Vue.use(Vuex)

// 准备actions对象--响应组件中用户的动作
const actions = {
  
  // 奇数的时候加
  incOdd(context, value) {
    if (context.state.sum % 2) {
      context.commit('INC', value)
    }
  },

  // 等一等再加
  incWait(context, value) {
    setTimeout(()=>{
      context.commit('INC', value)
    }, 500)
  }
}
//  准备mutations对象--修改state中的数据
const mutations = {
  // 加法的实现
  INC(state, value) {
    state.sum += value
  }, 

  // 减法的实现
  DEC(state, value) {
    state.sum -= value
  }
}
// 准备state对象--保存具体的数据
const state = {
  sum:0
}


// 创建并暴露store
export default new Vuex.Store({
  actions, mutations, state
})

在App.vue文件里:

<template>
  <div>
    <Count/>
  </div>
</template>

<script>
import Count from './components/Count.vue'

export default {
  name:'App',
  components:{Count}
}
</script>

<style>
  body {
    background-color: #e0e0e0;
  }
</style>

在Count.vue文件里:

<template>
  <div id="Count">
    <h1>当前求和为{{$store.state.sum}}</h1>
    <!-- 用v-model绑定n的值,用number限定词来限定n的值为数字 -->
    <select v-model.number="n">
      <option :value="1">1</option>
      <option :value="2">2</option>
      <option :value="3">3</option>
    </select>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
    <button @click="incrementOdd">当前求和为奇数再加</button>
    <button @click="incrementWait">等一等再加</button>
  </div>
</template>

<script>
export default {
  name:'Count',
  data() {
    return {
      n:1, // 用户选择的数字
    }
  },
  methods: {
    // 加法
    increment() {
      // 这里不走Actions,而是直接走Mutetions
      this.$store.commit('INC', this.n)
    },

    // 减法
    decrement() {
      // 这里不走Actions,而是直接走Mutetions
      this.$store.commit('DEC', this.n)
    },

    // 当sum的值为奇数的时候才加,不然就不加
    incrementOdd() {
      this.$store.dispatch('incOdd', this.n)
    },

    // 等一等再加
    incrementWait() {
      this.$store.dispatch('incWait', this.n)
    }
  },
}
</script>

<style scoped>
  #Count {
    margin: 0 auto;
    width: 80%;
  }

  button {
    margin-left: 5px;
  }

  button:hover,
  select:hover {
    cursor: pointer;
  }
</style>

getter的使用

  1. 概念:当state中的数据是需要加工后再使用的时候,可以使用getter加工

  2. store.js中追加getter配置

    ...
    const getter = {
        bigSum(state) {
            return state.sum * 10
        }
    }
    
    // 创建并暴露store
    export default new Vuex.Store({
        ...
        getters
    })
    
  3. 组件中读取数据:$store.getters.bigSum

四个map的使用

mapState方法

用于帮助我们映射state中的数据为计算属性

computed: {
	// 借助mapState方法生成计算属性:sum, school, subject(对象写法)
    ...mapState({sum:'sum', school:'school', subject:'subject'})
    
    // 借助mapState方法生成计算属性:sum, school, subject(数组写法)
    ...mapState(['sum', 'school', 'subject'])
}

mapGetters方法

用于帮助我们映射getter中的数据为计算属性

computed: {
    // 借助mapGetters生成计算属性:bigSum(对象写法)
    ...mapGetters({bigSum:'bigSum'})
    
    // 借助mapGetters生成基色属性:bigSum(数组写法)、
    ...mapGetters(['bigSum'])
}

mapActions方法

用于帮助我们生成actions对话的方法,即包含$store.dispatch(xx)的函数

methods: {
    // 靠mapActions方法生成:increment, decrement, incrementWait(对象形式)
    ...mapActions({increment:'increment', decrement:'decrement', incrementWait:'incrementWait'})
    
    // 靠mapActions方法生成:increment, decrement, incrementWait(数组形式)
    ...mapActions(['increment', 'decrement', 'incrementWait'])
}

mapMutations方法

用于帮助我们生成与mutations对话的方法, 即包含$store.commit(xxx)的函数

methods: {
    // 靠mapMutations生成:increment, decrement(对象形式)
    ...mapMutations({increment:'JIA', decrement:'JIAN'})
    
    // 靠mapMutations生成:increment, decrement(数组形式)
    ...mapMutations(['JIA', 'JIAN'])
}

备注:mapActions和mapMutations方法在使用的时候,若需要传递参数,需要:在模板中绑定事件时传递好参数,否则参数是事件对象

模块化+命名空间

  1. 目的:让代码更好维护,让多种数据分类更加明确

  2. 修改store.js

    const countAbout = {
        namespace: true, // 开启命名空间
        state: {sum: 0},
        mutations: {...},
        actions: {...},
        getters: {
            bigSum(state) {
                return state.sum * 10
            }
        }
    }
                    
    const personAbout = {
    	namespace: true,
        state: {...},
        mutations: {...},
        actions: {...},
    }
                    
    const store = new Vuex.Store({
    	modules: {
       		countAbout, personAbout
        }
    })
    
  3. 开启命名空间后,组件中访问state数据:

    // 方式一:自己直接读取
    this.$store.state.personAbout.list
    // 方式二:借助mapState读取
    ...mapState('countAbout', ['sum', 'school', 'subject'])
    
  4. 开启命名空间后:组件中读取getters数据

    // 方式一:自己直接读取
    this.$store.getters['personAbout/firstPersonName']
    // 方式二:借助mapGetters读取
    ...mapGetters('countAbout', ['bigSum'])
    
  5. 开启命名空间后,组件中调用dispatch

    // 方式一:自己直接dispatch
    this.$store.dispatch('personAbout/addPersonWang', person)
    // 方式二:借助mapActions
    ...mapActions('countAbout', {increment: 'jiaOdd', incrementWait: 'jiaWait'})
    
  6. 开启命名空间后,组件是调用commit

    // 方式一:自己直接调用commit
    this.$store.commit('personAbout/ADD_PERSON', person)
    // 方式二:借助mapMutations
    ...mapMutations('countAbout', {increment: 'JIA', decrement: 'J'})
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

绒毛鸭鸭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值