vuex的学习

vuex

vuex是个插件,用于多个组件操作共享变量

引入:数字操作案例
在这里插入图片描述

基于组件自定义事件而实现的操作数字案例如下:

App.vue

<template>
  <div id="app">
    <input class="num_input" type="text" v-model.number="sum">
    <!-- 下面是两个按钮 -->
    <AddOne :sum="sum" @MyAddOne="MyAddOne"/>
    <MultiTen :sum="sum" @MyMultiTen="MyMultiTen" />
  </div>
</template>

<script>
import AddOne from './components/AddOne.vue';
import MultiTen from './components/MultiTen.vue';

export default {
  name: 'App',
  components: {
    AddOne,
    MultiTen
  },
  data() {
      return {
        sum: 0
      }
  },
  methods: {
    MyAddOne(num) {
        this.sum = num;
    },
    MyMultiTen(num) {
        this.sum = num;
    }
  }
}
</script>

<style>
    #app {
        text-align: center;
        margin: 0 auto;
    }
     * {
      margin-bottom: 1px;
    }
    .num_input {
      text-align: center;
    }
</style>

AddOne.vue

    <div>
        <button @click="addOne">点我加1</button>
    </div>
</template>

<script>
    
    export default{		
        name: '',
        props: [ 'sum', 'MyAddOne'],
        data(){
            return{
                
            }
        },
        methods: {
            addOne() {
                this.$emit('MyAddOne', this.sum + 1);
            }
        },
    }
</script>


<style>
    
</style>

MultiTen.vue

    <div>
        <button @click="mutiTen">点我乘以10</button>
    </div>
</template>

<script>
    
    export default{		
        name: '',
        props: [ 'sum'],
        data(){
            return{
                
            }
        },
        methods: {
            mutiTen() {
                this.$emit('MyMultiTen', this.sum * 10);
            }
        },
    }
</script>
<style>
</style>

可以看出,对于每个子组件去操作父组件的数据,都需要子组件有触发函数$emit,父组件需要有回调函数,十分麻烦,而vuex对共享变量的管理就显得清晰且简单得多,下面简单介绍一下vuex。

6.1 vuex工作原理

工作原理图(下图来自vuex官网

在这里插入图片描述

state:保存共享的变量

actions:进行一些业务的逻辑,是可选的

mutations:唯一可以操作State中共享变量的地方

getter:state中共享变量的计算属性

举个例子:

Vue Components中通过 this.$store 【–> 调用dispatch(“aa”, 2) --> 触发actions里的 aa 函数 】–> commit(“aa”, 2) -->触发 mutations 的"AA"函数从而去操作state的数据 --> 改变state --> 重新渲染模板

【】中为actions的操作,是可选的

actions中的方法会可以显式传入参数 context 上下文

mutations中的方法需要传入参数 state, 第二个参数payload为可选(如果你想控制你变化数据的大小)

6.2 vuex的简单使用

基于上述的数字操作案例,用vuex实现

6.2.1 导入

vue2的项目应该使用 vuex3版本

npm i vuex@3

vue3的项目应该使用vuex4版本

npm i vuex@4

6.2.2 创建store文件夹及index.js

/store/index.js

import Vue from 'vue'
Vue.use(Vuex)
const store = new Vuex.Store({
    state: {
      sum: 1
    },
    mutations: {
      ADD(state, payload) {
        state.sum += payload;
      },
      MULTI(state, payload) {
        state.sum *= payload;
      }
    }
  });
  export default store

6.2.3 注册使用

main.js

import App from './App.vue'
import store from './store'

new Vue({
  render: h => h(App),
  store
}).$mount('#app')

6.2.4 其他

此时,在组件中可以使用 this.$store

App.vue

  <div id="app">
  	<!-- 通过this.$store.state.XXX 可以得到共享变量XXX -->
    <input class="num_input" type="text" v-model.number="this.$store.state.sum">
    <!-- 下面是两个按钮 -->
    <AddOne />
    <MultiTen />
  </div>
</template>

<script>
import AddOne from './components/AddOne.vue';
import MultiTen from './components/MultiTen.vue';

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

AddOne.vue

    <div>
        <button @click="addOne">点我加1</button>
    </div>
</template>

<script>
    
    export default{		
        name:'',
        methods: {
            addOne() {
               this.$store.commit("ADD", 1)
            }
        },
    }
</script>

MultiTen.vue

    <div>
        <button @click="mutiTen">点我乘以10</button>
    </div>
</template>

<script>
    export default{		
        name: '',
        methods: {
            mutiTen() {
               this.$store.commit('MULTI', 10)
            }
        },
    }
</script>

6.3 mapState

mapState可以帮我们在 this.$store.state 定义的共享变量作为计算属性自动生成

6.3.1 使用

导入

import {mapState} from 'vuex'

App.vue

import MultiTen from './components/MultiTen.vue';
import { mapState } from 'vuex';

export default {
  name: 'App',
  components: {
    AddOne,
    MultiTen
  },
  computed: {
    //这下面两个是等价的,都将 sum 作为计算属性sum显示到页面上
    //1.
    // sum() {
    //   return this.$store.state.sum;
    // },
    //2.
    //我们直接采用 mapState的数组写法
    // ...mapState(['sum'])
  }
}

如果要使用mapState、mapGettters、mapMutations、mapActions ,要求在 this.$store 里定义的东西的名字和在组件中使用的 mapXXX(‘[Name]’) 中的Name名字相同

mapGettters、mapMutations、mapActions 的使用基本同理,但需要在调用的地方传好参数 ,不太方便

举个例子:

/store/index.js

import Vue from 'vue'
Vue.use(Vuex)
const store = new Vuex.Store({
    state: {
      sum: 1
    },
    mutations: {
      ADD(state, payload) {
        state.sum += payload
      }
    }
  });
  export default store

App.vue

  <div id="app">
    <input class="num_input" type="text" v-model.number="sum">
    <!-- 需要一开始就定义好参数,所以更适合没参数的方法 -->
    <button @click="ADD(1)">点我加1</button>
  </div>
</template>

<script>
import { mapState, mapMutations } from 'vuex';

export default {
  name: 'App',
  computed: {
  	 // 需要和 this.$store.state中的sum变量同名
     ...mapState(['sum'])
  },
  methods: {
    // 需要和 this.$store.mutations中的ADD方法同名
    ...mapMutations(['ADD'])
  }
}
</script>

6.4 Vuex 分模块配置

const a = {
	namespaced: true //默认是false, 开启方便使用mapXXX
	actions:{},
	//....
}
const b = {
	//...
}

export default new Vue.store({
	modules:{
		a : [变量1],
		b : [变量2]
	}
})

此时,通过组件的 this.$store.state.[模块名] 去获取state对应的内容

通过组件的 this.$store.getters.[‘模块名/对应内容’]去获取getters中的内容

dispatch 和 commit 通过 this.$store.[commit / dispatch](‘模块名/内容名’)

mapState, mapGetters 写成 …mapXXX('模块名 ', [‘数组内容’],)

mapActions 和 mapMutations 需要写成 …mapXXX(‘模块名’,{xx: xx})

举个例子:
/store/index.js

import Vue from 'vue'
Vue.use(Vuex)

const a = {
    namespaced: true, //默认是false, 开启方便使用mapXXX
    state: {
        s_age: 1
    }
}
const b = {
    namespaced: true, //默认是false, 开启方便使用mapXXX
    state: {    
        t_age: 2
    },
    mutations: {
        ADD_ONE_TEACHER(state) {
            state.t_age++
        }
    }
}
const store = new Vuex.Store({
   modules: {
      // 冒号前面的是模块名,后面的是const定义的常量名
      student : a,
      teacher : b
   }
  });
  export default store

App.vue

  <div id="app">
    <input class="num_input" type="text" v-model.number="s_age">
    <input class="num_input" type="text" v-model.number="t_age">
    <button @click="ADD_ONE_TEACHER(1)">点我加1</button>
  </div>
</template>

<script>
import { mapState, mapMutations } from 'vuex';

export default {
  name: 'App',
  computed: {
    ...mapState('teacher', ['t_age']),
     
    //以下两种是等效的
    //1.
    // s_age() {
    //   return this.$store.state.student.s_age
    // },
    //2.
     ...mapState('student', ['s_age']),
    
  },
  methods: {
    //以下两种是等效的
    //1. 
    // ADD_ONE_TEACHER(num) {
    //   this.$store.commit('teacher/ADD_ONE_TEACHER', num)
    // },
    //2.
    ...mapMutations('teacher', {ADD_ONE_TEACHER: 'ADD_ONE_TEACHER'})
  }
}
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值