vue的组件通信

什么是vue的组件通信

组件:是可以复用的vue实例
组件通信:每个组件是一个单独的整体,组件之间互相联系,就是组件通信

组件关系图组件在这里插入图片描述
如图所示:A与B、A与C、B与D、C与E为父子关系,B与C为兄弟关系,A与D、A与E隔代亲,D与E为堂兄弟关系 ,可以将组件的关系归为两类:

  • 父子关系
  • 非父子关系(兄弟和隔代亲等…)

1、父子组件之间传递

1.1 父传子 props
   1、数据存放在父组件中,在父组件中 给子组件添加一个属性,把值传给子组件
   2、子组件中 使用props 进行接收  props:[]
// Parent.vue
<div id="app" style="border: 3px solid #000; margin: 20px">
    我是父组件
    <Son :title="title"></Son>
</div>
data() {
    return {
      title: '这是一个大标题',
    }
  },

// Son.vue
<template>
  <div class="son" style="border: 3px solid #000; margin: 20px; padding: 10px">
    我是son组件
    <p>{{ title }}</p>
  </div>
</template>

<script>
export default {
  name: 'MyMson',
  // 简单写法
  // props: ['title'],
  // 完整写法
  props:{
  	title:{
  		type:String,  // 类型
  	    required: true,  // 是否必填
        default: 40, // 默认值
        // 自定义校验
  		validator(value){}
  	}
  }
}
</script>

<style></style>
 
1.2 子传父 $emit
 子组件利用$emit通知父元素,进行修改更新
 1、在子组件中 $emit 触发事件,给父组件发送消息通知
 2、父组件监听事件,
 3、提供处理函数,形参中获取参数
// 父组件 Parent.vue
<template>
  <div id="app" style="border:3px solid #000;margin:20px">
    我是父组件
     <!-- 2、父组件需要对于子元素设置的事件进行监听 -->
    <Son :title="title" @changeTitle="fatherFn"></Son>
  </div>
</template>

<script>
import Son from './components/Son.vue'
export default {
  // 父组件的数据
  data(){
    return {
      title: '这是一个大标题',
    }
  },
  methods:{
    // 3、提供处理函数,处理逻辑
    fatherFn(txt) {
      console.log(txt)
      this.fatherDate = txt
    }
  },
  components:{ Son }
}
</script>

// 子组件 Son.vue
<template>
  <div class="son" style="border:3px solid #000;margin:20px">
    我是son组件 {{ title }}
    <button @click="changeFn">修改标题</button>
  </div>
</template>

<script>
export default {
  props:{
  	title:String
  },
  methods:{
    changeFn() {
      // 1、通过$emit,向父组件发送数据
      this.$emit('changeTitle','略略略~')
    }
  }
}
</script>

优化:

父子之间传参可以使用 v-model 传参

  1. 把需要给子组件传递的属性名修改为 value
  2. 子组件给父组件传递的事件名称修改为 input

注意点:
1、父级prop的数据更新,会向下流动,影响子组件。这个数据流动是单向的
2、子组件不可以修改父组件传的数据

2、非父子之间

2.1 eventBus 事件总线
  可通过 EventBus 进⾏信息的发布与订阅。 (创建一个都能访问到的事件总线)
	// EventBus.js
	// 1、创建一个都能访问到的事件总线(空的vue实例)
	import Vue from 'vue'
	const Bus = new Vue()
	export default Bus
	
 	// 2、在A组件(接收方),进行监听Bus事件(订阅消息)
    Bus.$on('事件名',参数 => { ... })
    
	// 3、B组件中, 触发 bus的事件
	Bus.$emit('事件名','参数')

具体实现代码

组件A

<template>
  <div class="baseA">
    我是A组件(接收方)
    {{data}}
  </div>
</template>

<script>
import Bus from '../utils/EventBus'
export default {
  data(){
    return {
      data:''
    }
  },
  created() {
    // 2、在A组件(接收方),进行监听Bus事件(订阅消息)
    Bus.$on('sendMsg',msg => {
      // console.log(msg)
      this.data = msg
    })
  }
}
</script>

<style scoped>
.baseA {
  width: 200px;
  height: 150px;
  padding: 10px;
  margin-top: 10px;
  border: 3px solid #000;
  border-radius: 5px;
  font-size: 20px;
}

</style>

组件B

<template>
  <div class="baseA">
    我是B组件(发布方)
    <button @click="send">发布通知</button>
  </div>
</template>

<script>
import Bus from '../utils/EventBus'
export default {
  methods:{
    send() {
      // 3、在B组件(发送方)触发事件传递参数,帆布消息
      Bus.$emit('sendMsg','我是B组件发过来的信息')
    }
  }
}
</script>

<style scoped>
.baseA {
  width: 200px;
  height: 150px;
  padding: 10px;
  margin-top: 10px;
  border: 3px solid #000;
  border-radius: 5px;
  font-size: 20px;
}

</style>
2.2、provide 和 inject (跨层级共享数据)

简单来说就是 父组件 中通过 provide 来提供变量, 然后在 子组件 中通过 inject 来注入变量。

注意: 这对选项需要一起使用,不论子组件嵌套有多深, 只要调用了inject 那么就可以注入provide中的数据,而不局限于只能从当前父组件的props属性中数据

provide 选项应该是一个对象或返回一个对象的函数
inject 选项是一个字符串数组,或一个对象

	// A.vue
 	provide() {
    	return {
      		// 简单数据类型(非响应式)
      		color: this.color,
      		// 复杂数据类型(响应式)推荐
      		userInfo: this.userInfo,
   	 	};
  	},
	// GrandSon.vue
	<template>
  		<div class="grandSon">
    		我是GrandSon
    		{{ color }} - {{ userInfo.name }} - {{ userInfo.age }}
  		</div>
	</template>

	<script>
	export default {
  		inject: ["color", "userInfo"],
	};
	</script>

	<style>
	 .grandSon {
  		border: 3px solid #000;
  		border-radius: 6px;
  		margin: 10px;
  		height: 100px;
	 }
	</style>
2.3、 $attrs 和 $listeners

​ 可以用来作为跨级组件之间的通信机制

父组件

<template>
  <div>
    <my-child1 :money="100" desc='你好哇' @test1="fn1" @test2="fn2"></my-child1>
  </div>
</template>

子组件

<template>
  <div class="my-child1">
    <!-- $attrs => { "money": 100, "desc": "你好哇" } -->
    <div>{{ $attrs }}</div>
    <my-child2 v-bind="$attrs" v-on="$listeners"></my-child2>
  </div>
</template>

<script>
import MyChild2 from './my-child2'
export default {
  created() {
    console.log(this.$listeners)
  },
  components: {
    MyChild2,
  },
}
</script>

孙组件

<template>
  <div>
    我是child2 - {{ money }} - {{ desc }}
    <button @click="clickFn">按钮</button>
  </div>
</template>

<script>
export default {
  props: ['money', 'desc'],
  methods: {
    clickFn () {
      this.$emit('test1', '嘎嘎')
      this.$emit('test2', '嘿嘿')
    }
  }
}
</script>
2.4、vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

如果需要构建一个中大型单页应用,可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

vuex的模块

state: 存放数据

mutations: 存放操作数据的方法

actions: 存放一些异步操作 (也可以进行一些同步处理) 注意: actions 是不能直接修改 state 数据的, 需要提交 mutation

getters: 存放基于 state 计算出来的一些值 (计算属性)

modules: 分模块, 项目大了, 也推荐分模块管理 (同模块的 vuex 操作, 就会在一起)

the end…
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值