【Vue3】Vue组件之间的三种通信

一、父子组件之间的传值

1.父组件向子组件传值

子组件通过props属性获取父组件中的值

  • 在父组件中使用子组件时,需要通过v-bind指令绑定一个属性
  • 在子组件中通过props属性,来获取父组件中v-bind指令绑定的那个属性

Father.vue代码段:

<template>
    <Son v-bind:users="arr"/>
</template>

<script>
import Son from "./Son.vue";

export default {
  name: "Father",
  setup(){
    const arr = ['大雁塔','小雁塔','兵马俑','大唐芙蓉园','乾陵']
    return {
      arr
    }
  },
  components:{
    Son
  }
}
</script>

<style scoped>

</style>

Son.vue代码段:

<template>
<ul>
  <li v-for = "(user,index) in users" v-bind:key="index">
    {{ user }}
  </li>
</ul>
</template>

<script>
export default {
  name: "Son",
  props:{
    users:{
      type:Array,
      required:true
    }
  }
}
</script>

<style scoped>
  li{
    list-style-position: inside;
  }
</style>

App.vue代码:

import Father from "./components/Father.vue"
<Father/>

2.子组件向父组件传值

通过触发事件的方式传递(使用$emit触发自定义的事件)

FatherOne.vue代码段:

<template>
<SonOne v-on:updateTitle="modifyTitle"/>
  <h1>{{ title }}</h1>
</template>

<script>
import { ref } from 'vue';
import SonOne from "./SonOne.vue";
export default {
  name: "FatherOne",
  components: {
    SonOne
  },
  setup(){
    let title = ref('我是父组件,用来接收子组件的值')
    function modifyTitle(info){
      title.value = info
    }
    return {
      title,
      modifyTitle
    }
  }
}
</script>

<style scoped>

</style>

SonOne.vue代码段:

<template>
<h1 @click="changeTitle">{{ title }}</h1>
</template>

<script>
import {ref,getCurrentInstance} from "vue";

export default {
  name: "SonOne",
  setup(){
    let title = ref("我是子组件,单机我,传值给父组件")
    const { proxy } = getCurrentInstance()
    function changeTitle(){
      proxy.$emit('updateTitle','西安邮电大学')
    }
    return{
      title,
      changeTitle
    }
  }
}

</script>

<style scoped>

</style>

App.vue代码段:

import FatherOne from "./components/FatherOne.vue";
 <FatherOne/>

3.在组合式API(setup)中使用this所出现的问题(子传父)

  • this:代表当前的组件(Vue2)
  • 在Vue3的setup中没有this,但是有proxy,作用与this的作用相同

获取proxy的方法:

        第一步:从vue中导入方法:getCurrentInstance

                import { getCurrentInstance } from ‘vue’;

        第二步:从getCurrentInstance方法中获取proxy

                const { proxy } = getCurrentInstance()

强调:

        ①setup中没有this,可以使用proxy,其作用与this相同

        ②在setup中定义普通变量,建议使用ref进行初始化。改变用ref初始化的变量的值,采用的方法

                变量名.value = ‘新值’

        ③在setup中定义普通对象,建议使用reactive进行初始化

                const obj = reactive({})
 

二、 兄弟组件之间的传值

兄弟组件之间的传值:使用mitt第三方库。

1.创建事件中心:

创建事件触发器并导出

event.js代码段:

//创建事件中心
import mitt from 'mitt'; //导入mitt
const emitter = mitt() //创建事件触发器
export default emitter;//导出事件触发器

2.兄弟组件定义接收数据方法:

对指定事件进行监听

3.兄弟组件定义发送数据方法:

触发对方监听的事件并发送数据

Brother1.vue代码段:

<template>
   <div class = "Brother1">
     <h2>兄弟 --- 关羽</h2>
     <p>{{ data1 }}&nbsp;&nbsp;&nbsp;&nbsp;{{ data2 }}</p>
     <button @click="sendData">将美酒送给三弟</button>
   </div>
</template>

<script>
//导入事件中心的事件触发器
import emitter from '../event/event'

export default {
  name: "Brother1",
  data(){
    return{
      data1:'美酒',
      data2:''
    }
  },
  methods:{
    //接收数据的方法
    receive: function(){
      //通过事件触发器来监视“two-to-one"事件是否被触发,若被触发则接收触发该事件的组件传递的组件
      emitter.on('two-to-one',(data)=>{
        this.data2 = data
      })
    },
    sendData:function(){
      //触发指定事件,将数据传递给对应的事件
      emitter.emit('one-to-two',this.data)
    }
  },

  mounted(){//表示组件挂在完成,只要组件挂载完成mounted下的代码就立即执行
    this.receive();

  }
}
</script>

<style scoped>
.Brother1{
  color: blueviolet;
  font-size: 20px;
  border: 1px solid #bbb;
  margin-bottom: 10px;
}

</style>

Brother2.vue代码段:

<template>
  <div class = "Brother2">
    <h2>兄弟 --- 张飞</h2>
    <p>{{ data1 }}&nbsp;&nbsp;&nbsp;&nbsp;{{ data2 }}</p>
    <button @click="sendData">将宝剑送给二哥</button>
  </div>
</template>

<script>
//导入事件中心的事件触发器
import emitter from '../event/event'
export default {
  name: "Brother2",
  data(){
    return{
      data1:'宝剑',
      data2:''
    }
  },
  methods:{
  //  监听one-to-two事件,接收数据
    receive:function(){
      emitter.on('one-to-two',(data)=>{
        this.data2 =data
      })
    },
    sendData(){//发送数据,触发”two-to-one‘事件
      //触发指定事件,将数据传递给对应的事件
      emitter.emit('two-to-one',this.data)

    }
  },
  mounted(){//表示组件挂在完成,只要组件挂载完成mounted下的代码就立即执行
    this.receive();

  }
}
</script>

<style scoped>
.Brother2{
  color: yellowgreen;
  font-size: 20px;
  border: 1px solid #ccc;
}
</style>

App.vue代码段:

import Brother1 from "./components/Brother1.vue";
import Brother2 from "./components/Brother2.vue";
<Brother1/>
<Brother2/>

三、跨级组件之间的通信

跨级组件之间的通信:使用provide / inject方法,provide发送数据,inject接收数据。

1.provide( name,value )

name:是属性名
value:属性值

2.inject(name,default)

name:是属性名。必须和provide的属性名相同
default:可选参数

KangXi.vue代码段:(爷爷)
 

<template>
<h2>康熙:{{ lastWords}}</h2>
  <hr/>
  <YongZheng/>

</template>

<script>
import { provide } from 'vue';
import YongZheng from './YongZheng.vue'
export default {
  name: "KangXi",
  components:{
    YongZheng
  },
  setup(){
    let lastWords = '整顿吏治'
    provide('giveLastWords',lastWords)

    return{
         lastWords
    }
  }
}
</script>

<style scoped>

</style>

YongZheng.vue代码段:(儿子)

<template>
<h2>儿子:雍正</h2>
  <div>父亲: {{ getFatherData }}</div>
  <hr/>
  <QianLong/>
</template>

<script>
import { inject } from 'vue';
import QianLong from "./QianLong.vue";
export default {
  name: "YongZheng",
  components: {
    QianLong
  },
  setup(){
    let getFatherData = inject('giveLastWords')
    return {
      getFatherData
    }
  }
}
</script>

<style scoped>

</style>

QianLong.vue代码段:(孙子)

<template>
<div>
  <h2>孙子:乾隆</h2>
  <div>爷爷:{{ getYeYeData }}</div>
</div>
</template>

<script>
import { inject } from 'vue';
export default {
  name: "QianLong",
  setup(){
    let getYeYeData = inject('giveLastWords')
    return {
      getYeYeData
    }
  }
}
</script>

<style scoped>

</style>

App.vue代码段:

import KangXi from "./components/KangXi.vue";
  <KangXi/>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值