(详细)vuex入门及使用

vuex入门及使用

一、什么是vuex

专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间的通信的方式,且适用于任意组件间的通信。

Github 地址: https://github.com/vuejs/vuex

二、vuex的工作原理图

请添加图片描述
理解原理图:

Vue Components 组件:客人
Vuex:餐厅
Actions:服务员
Mutation:后厨
State:菜品
1、客人来到餐厅
跟服务员说(发起dispatch请求)想吃蛋炒饭,服务员确认有没有蛋炒饭(验证),有的话,转告给(发起commit请求)后厨,后厨开始做菜(执行客人的命令),做好的菜(State)上传给客人。
2、如果客人和后厨认识,即可略过服务员,直接跟后厨说(发起dispatch请求)吃蛋炒饭,后厨直接做菜上传。

三、什么时候使用vuex

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

四、vuex的核心概念

1、state

  • vue管理的状态对象
  • 是唯一的

2、actions

  • 值为一个对象,包含多个响应用户动作的回调函数
  • 通过 commit( )来触发 mutation 中函数的调用, 间接更新
  • 触发actions 中的回调–在组件中使用: $store.dispatch(‘对应的 action 回调名’) 触发
  • 可以包含异步代码(定时器, ajax 等等

3、mutations

  • 值是一个对象,包含多个直接更新 state 的方法
  • 在 action 中使用:commit('对应的 mutations 方法
  • 不能写异步代码、只能单纯的操作 state
    4、getters
  • 值为一个对象,包含多个用于返回数据的函数
  • 使用: $store.getters.xxx
    5、modules
  • 包含多个 module
  • 一个 module 是一个 store 的配置对象
  • 与一个组件(包含有共享数据)对应

五、案例 --模块化

1、创建一个vue项目,在idea中打开并在main.js中导入需要的文件
在这里插入图片描述
2、第一个组件 求和案例

<template>
<!-- src_求和案例 -->
<div>
  <h1>当前求和为:{{sum}}</h1>
  <h3>当前求和放大十倍为:{{bigSum}}</h3>
  <h3>我在{{school}}学习{{subject}}</h3>
  <h3 style="color: red">Person组件的总人数是:{{personList.length}}</h3>

  <select v-model.number="n">
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
  </select>
  <button @click="JIA(n)">+</button>
  <button @click="JIAN(n)">-</button>
  <button @click="jiaOdd(n)">当前求和为奇数再加</button>
  <button @click="jiaWait(n)">等一等再加</button>
</div>
</template>

<script>
/*求和案例 mapState和mapGetters,mapMutations,mapActions的用法*/
import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
export default {
  name: "Count",
  data(){
    return{
      n:1,  //用户选择的数字
    }
  },
  computed:{
  //靠自己去写计算属性

    //借助mapState生成计算属性 从state中读取数据(对象写法)
  //   ...mapState({'he':'sum','xuexiao':'school','xueke':'subject'})

    //借助mapState生成计算属性 从state中读取数据(数组写法)  名字必须一致
  // ...mapState(['sum','school','subject','personList']),

    //这样可以读取vuex两个模块的数据 但上面调用的话要countAbout.  personAbout. 点出来
  //...mapState(['countAbout','personAbout']),

  ...mapState('countAbout',['sum','school','subject']),
  ...mapState('personAbout',['personList']),

    //借助mapGetters生成计算属性  (对象写法)
    // ...mapGetters({bigSum:'bigSum'}),
    //借助mapGetters生成计算属性  (数组写法)
    ...mapGetters('countAbout',['bigSum'])
  },
  methods:{
    //靠自己去写方法
    /*increment(){
      this.$store.commit('JIA',this.n)
    },
    decrement(){
      this.$store.commit('JIAN',this.n)
    },*/

    //借助mapMutations生成对应的方法 方法中会调用commit去联系mutations(对象写法)
    // ...mapMutations({increment: 'JIA',decrement: 'JIAN'}),

    // 借助mapMutations生成对应的方法 方法中会调用commit去联系mutations(数组写法)
     ...mapMutations('countAbout',['JIA','JIAN']),
     
    /*incrementOdd(){
        this.$store.dispatch('jiaOdd',this.n)
    },
    incrementWait(){
        this.$store.dispatch('jiaWait',this.n)
    }*/

    //借助mapActions生成对应方法 方法中调用dispatch去联系actions (对象方法)
    ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'}),

    //借助mapActions生成对应方法 方法中调用dispatch去联系actions (数组方法)
    ...mapActions('countAbout',['jiaOdd','jiaWait'])

  },
  //借助mapstate生成计算属性 从state中读取数据 (对象写法)
  mounted() {
   // const x=mapState({'he':'sum','xuexiao':'school','xueke':'subject'})
    //console.log(x)
  }
}
</script>

<style lang="css">
button{
  margin-left: 5px;
}
</style>

3、第二个组件 人员案例 没有使用mapState和mapGetters,mapMutations,mapActions的用法

<template>
<div>
  <h1>人员列表</h1>
  <h3 style="color: red">Count组件求和为:{{sum}}</h3>
  <h3>列表中第一个人的名字是:{{firstPersonName}}</h3>
  <input type="text" placeholder="请输入名字" v-model="name">
  <button @click="add">添加</button>
  <button @click="addWang">添加一个姓王的人</button>
  <ul>
    <li v-for="p in personList" :key="p.id">{{p.name}}</li>
  </ul>
</div>
</template>

<script>
// import {mapState} from 'vuex'
export default {
  name: "Person",
  data(){
    return{
      name:''
    }
  },
  computed:{
    // ...mapState(['personList']),
    personList(){
      return this.$store.state.personAbout.personList
    },
    sum(){
      return this.$store.state.countAbout.sum
    },
    firstPersonName(){
      return this.$store.getters['personAbout/firstPersonName']
    }
  },
  methods:{
    add(){
      const person ={id:Math.ceil(Math.random()*10000),name:this.name}
      this.$store.commit('personAbout/ADD_PERSON',person)
      this.name = ''
    },
    addWang(){
      const person ={id:Math.ceil(Math.random()*10000),name:this.name}
      this.$store.dispatch('personAbout/addPersonWang',person)
      this.name = ''
    }
  }
}
</script>

<style scoped>

</style>

所以在访问store中的数据时 使用/

this.$store.commit('personAbout/ADD_PERSON',person)
this.$store.dispatch('personAbout/addPersonWang',person)

mapState和mapGetters,mapMutations,mapActions的用法
1、生成计算属性
借助mapState生成计算属性 从state中读取数据(对象写法)

 ...mapState({'he':'sum','xuexiao':'school','xueke':'subject'})

借助mapState生成计算属性 从state中读取数据(数组写法) 名字必须一致

 ...mapState(['sum','school','subject','personList']),

这个方式可以 读取vuex两个模块的数据 但上面调用的话要countAbout. personAbout. 点出来 记住一定要将store中index.js中的命名空间开启!

...mapState(['countAbout','personAbout']),

2、生成对应的方法
借助mapMutations生成对应的方法 方法中会调用commit去联系mutations(对象写法)

...mapMutations({increment: 'JIA',decrement: 'JIAN'}),

借助mapMutations生成对应的方法 方法中会调用commit去联系mutations(数组写法)

 ...mapMutations('countAbout',['JIA','JIAN']),

借助mapActions生成对应方法 方法中调用dispatch去联系actions (对象方法)

...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'}),

借助mapActions生成对应方法 方法中调用dispatch去联系actions (数组方法)

...mapActions('countAbout',['jiaOdd','jiaWait'])

借助mapstate生成计算属性 从state中读取数据 (对象写法)

  mounted() {
	 const x=mapState({'he':'sum','xuexiao':'school','xueke':'subject'})
    //console.log(x)
  }

4、store中的index.js

//该文件用于创建vuex中最核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)

//求和功能的相关配置
const countOptions={
  //开启命名空间
  namespaced:true,
  actions:{
    jiaOdd(context,value) {
      if(context.state.sum % 2){
        context.commit('JIA',value)
      }
    },
    jiaWait(context,value) {
      setTimeout(()=>{
        context.commit('JIA',value)
      },500)
    }
  },
  mutations:{
    JIA(state,value){
      console.log('mutation中的JIA')
      state.sum += value
    },
    JIAN(state,value){
      state.sum -= value
    },
  },
  state:{
    sum:0, //当前的和
    school: '尚硅谷',
    subject:'前端',
  },
  getters:{
    bigSum(state){
      return state.sum*10
    }
  },
}

//人员功能的相关配置
const personOptions={
  namespaced:true,
  actions:{
    addPersonWang(context,value){
      if(value.name.indexOf('王')===0){
        context.commit('ADD_PERSON',value)
      }else{
        alert("添加的人必须姓王")
      }
    }
  },
  mutations:{
    ADD_PERSON(state,value){
      console.log("add person 被调用了")
      state.personList.unshift(value)
    }
  },
  state:{
    personList:[
      {id:'001',name:'张三'}
    ],
  },
  getters:{
    firstPersonName(state){
      return state.personList[0].name
    }
  },
}

//创建store并导出
export default new Vuex.Store({
  modules:{
    countAbout:countOptions,
    personAbout:personOptions
  }
})

附:运行结果
在这里插入图片描述

以下是store对象中的五个属性及用法

//state--用于存储数据
  state: {},
  //mutations--用于操作数据(state)
  mutations: {},
  //actions---用于响应组件中的动作
  actions: {},
  //modules--用于存放多个组件的不同数据及操作加工等
  modules: {},
  //getters:用于将state中的数据进行加工
  getters:{}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值