Vue组件间通信

一、props

适用于:

1)父组件 —> 子组件 通信
在子组件定义props,在父组件中引入子组件,并在子组件标签绑定要传递的数据

 // 父组件
<template>
 	<div class="father">
 		// 传固定String
 		<Child :msg="123123" />
	</div>
</template>

<script>
	// 引入子组件
	import Child from "./child"
	export default {
		data () {
			return {}
		},
		components: {
			Child
		},
	}
</script>

 // 子组件
<template>
 	<div class="child">
 		<span>{{msg}}</span>
	</div>
</template>

<script>
	export default {
		data () {
			return {}
		},
		// 接收来自父组件的数据; props可以是数组,也可以是对象(校验)
		// props: [ 'msg' ]
		props: {
			msg: {
				type: String, // 指定msg类型
				require: false, // 是否必传,这里如果为true,在父组件不传msg,页面会报错
				default: "啦啦啦" // msg的默认值
			}
		}
	}
</script>

2)子组件 —> 父组件 通信(要求父先给子一个函数)
在这里插入图片描述

3)路由组件传递props :布尔值、对象、函数
在这里插入图片描述

二、自定义事件

  1. 适用于:子传父
  2. 使用场景:子组件想给父组件传数据,就要在父组件中给子组件中绑定自定义事件(事件的回调留在父组件中)
  3. 绑定自定义事件

1)第一种方式:在父组件中:

 <Demo @fandou="test"/><Demo v-on:fandou="test"> //<Demo/>是子组件

2)第二种方式:在父组件中:

<Demo ref="demo"/>
   ......
   mounted() {
        this.$refs.xxx.$on("fandou",this.test)
   }

3)若想自定义事件只能触发一次,可以使用once修饰符,或$once方法

  1. 触发自定义事件:this.$emit(‘fandou’,数据)
  2. 解绑自定义事件:this.$off(‘fandou’)
  3. 组件上也可以绑定原生DOM事件,需要使用native修饰符
  4. 注意:通过this.$ refs.xxx.$on(“fandou”,回调)绑定自定义事件,回调要么配置在methods,要么用箭头函数,否则this指向会出现问题

在这里插入图片描述
第二种写法:使用ref
在这里插入图片描述

三、全局事件总线$bus

  1. 适用于任意组件间通信
  2. 安装全局事件总线:在入口文件main.js中
new Vue ({
	......
	beforeCreate() {
		Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm
	},
	......
})
  1. 使用事件总线

1)接收数据:A组件想接收数据,则在A组件中给$bus绑自定义事件,事件的回调留在A组件中

	methods() {
		demo(data) {
			......
		},
	},
	mounted() {
		this.$bus.$on('xxx',this.demo)
	}

2) 提供数据: this. b u s . bus. bus.emit(‘xxx’,demo)
4. 最好在beforeDestory钩子中,用$off去解绑当前组件所用到的事件

在这里插入图片描述

四、消息订阅与发布(pubsub-js)

  1. 适用于任意组件间通信
  2. 引入:import pubsub from ‘pubsub-js’
  3. 接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身
methods(){
    demo(data){
      ......
    },
},
......
mounted() {
    this.pid = pubsub.subscribe('xxx',this.demo)   //订阅消息
}
  1. 提供数据:pubsub.publish(‘xxx’,数据)
  2. 最好在beforeDestroy钩子中,用pubsub.unsubscribe(pid)
    在这里插入图片描述

五、Vuex

  1. 在Vue中实现集中式状态(数据)的管理的一个Vue插件,对Vue应用中多个组件的共享状态进行集中式的管理(读/写),适用于任意组件间通信
  2. 何时使用? ————多个组件需要共享数据时
  3. 搭建Vuex环境
    1)创建文件: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 = {}
       	// 准备getters——用于加工数据
       	const getters = {}

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

2)在main.js中创建vm时传入store配置项

        ......
        //引入store
        import store from './store'
        ......
        //创建vm
        new Vue({
            el:'#app',
            render: h => h(App),
            store
        })
  1. 组件读取vuex中的数据:$store.state.xxx || $store.getters.yyy
  2. 组件中修改vuex中的数据:$store.dispatch(‘action中的方法名’,数据) 或 $store.commit(‘mutations中的方法名’,数据)
  3. 备注:若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写dispatch,直接编写commit
  4. 四个map方法的使用
    1)mapState方法:用于帮助我们映射state中的数据为计算属性
computed: {
    //借助mapState生成计算属性:sum、school、subject(对象写法)
    ...mapState({sum:'sum',school:'school',subject:'subject'})
    //借助mapState生成计算属性:sum、school、subject(数组写法)
    ...mapState(['sum','school','subject'])
}

2)mapGetters方法:用于帮助我们映射gettes中的数据为计算属性

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

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

    methods:{
        //靠mapActions生成:incrementOdd、incrementWait(对象形式)
        ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'}),
        //靠mapActions生成:incrementOdd、incrementWai(数组形式)
        ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'}),
    }

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

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

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

  1. 模块化 + 命名空间
    1. 目的:让代码更好维护,让多种数据分类更加明确
    2. 修改store.js
        const countAbout = {
            namespaced:true,//开启命名空间
            state:{x:1},
            mutations:{....},
            actions:{....},
            getters:{
                bigSum(state) {
                    return state.sum * 10
                }
            }
        }

        const personAbout = {
            namespaced:true,//开启命名空间
            state:{....},
            mutations:{....},
            actions:{....},
        }

        const store = new Vuex.Store({
            modules:{
                countAbout:countOptions,
                personAbout:personOptions
            }
        })
  1. 开启命名空间后,组件中读取state数据:
        //方式一:自己直接读取
        this.$store.state.personAbout.list
        //方式二:借助mapState读取
        ...mapState('countAbout',['sum','school','subject']),
  1. 开启命名空间后,组件中读取getters数据:
        //方式一:自己直接读取
        this.$store.getters['personAbout/firstPersonName']
        //方式二:借助mapState读取
        ...mapGetters('countAbout',['bigSum'])
  1. 开启命名空间后,组件中调用dispatch
        //方式一:自己直接dispatch
        this.$store.dispatch('personAbout/addPersonXiao',person)
        //方式二:借助mapActions:
        ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
  1. 开启命名空间后,组件中调用commit
        //方式一:自己直接commit
        this.$store.commit('personAbout/ADD_PERSON',person)
        //方式二:借助mapMutations:
        ...mapActions('countAbout',{increment:'JIA',decrement:'jIAN'})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值