vue3组件通信(记录所有遇到的通信方式,以后看到新的方式会追加)

目录

一、父传子

1、props

2、ref

3、provide-inject(传子组件及后代组件) 

二、子传父

1、emit

2、$parent

3、v-model

三、全局组件通信

1、pinia


一、父传子

1、props
// --------------------------------------------------------父组件
<template>
  <div>父组件</div>
  <ChildPage :car="che" :money="qian"></ChildPage>
</template>

<script setup lang="ts">
import ChildPage from '@/components/ChildPage.vue'
import { ref } from 'vue'

let che = ref('奔驰')
let qian = ref(100000)
</script>



// ---------------------------------------------------------子组件
<template>
  <div>子组件</div>
  <div>子组件收到父组件的车:{{ props.car }}</div>
  <div>子组件收到父组件的钱:{{ props.money }}块</div>
</template>

<script setup lang="ts">
//defineProps是Vue3提供方法,不需要引入直接使用

// 数组写法
// let props = defineProps(['car', 'money'])

// 对象写法,可以规定数据类型和默认值等
let props = defineProps({
  car: {
    type: String,
    required: true //是否规定必须得有
  },
  money: {
    type: Number,
    required: false, //是否规定必须得有
    default: 9999 //默认数据,当父组件没有传递数据时,读取该数据
  }
})
</script>

<style lang="scss" scoped></style>
2、ref
// --------------------------------------------父组件
<template>
  <div>父组件</div>
  <ChildPage ref="son"></ChildPage>
  <button @click="add">给子组件10块钱</button>
  <button @click="shengyu">给子组件留100块钱</button>
</template>

<script setup lang="ts">
import ChildPage from '@/components/ChildPage.vue'
import { ref } from 'vue'

let son = ref()

const add = () => {
  // 父组件调用子组件函数传值
  son.value.addMoney(10)
}

const shengyu = () => {
  // 父组件直接修改子组件变量的值
  son.value.money = 100
}
</script>



// --------------------------------------------子组件
<template>
  <div class="son">
    <h3>我是子组件:{{ money }}</h3>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
//儿子钱数
let money = ref(666)
const addMoney = (num: number) => {
  money.value += num
}
//组件内部数据对外关闭的,别人不能访问
//如果想让外部访问需要通过defineExpose方法对外暴露
defineExpose({
  money,
  addMoney
})
</script>
3、provide-inject(传子组件及后代组件) 

父组件:用provide传输对应的数据,并提供一个key,后续的子组件在拿数据也是根据此key

孙组件:数据可以进行修改,而且所有的组件数据都是同步的

// -----------------------------------------父组件
<template>
  <div>父组件</div>
  <div>{{ car }}</div>
  <ChildPage></ChildPage>
</template>

<script setup lang="ts">
import ChildPage from '@/components/ChildPage.vue'

//vue3提供provide(提供)与inject(注入),可以实现隔辈组件传递数据
import { ref, provide } from 'vue'
let car = ref<string>('法拉利')
//祖先组件给后代组件提供数据
//两个参数:第一个参数就是提供的数据key
//第二个参数:祖先组件提供数据
provide('TOKEN', car)
</script>


// ------------------------------------------子组件
<template>
  <div class="child">
    <h1>我是子组件1{{ car }}</h1>
    <Child></Child>
  </div>
</template>

<script setup lang="ts">
import Child from './GrandChild.vue'
import { inject } from 'vue'
//注入祖先组件提供数据
//需要参数:即为祖先提供数据的key
let car = inject('TOKEN')
</script>

//-------------------------------------------孙组件
<template>
  <div class="child1">
    <h1>孙子组件</h1>
    <p>{{ car }}</p>
    <button @click="updateCar">更新数据</button>
  </div>
</template>

<script setup lang="ts">
import { inject } from 'vue'
//注入祖先组件提供数据
//需要参数:即为祖先提供数据的key
let car = inject('TOKEN')
const updateCar = () => {
  car.value = '自行车'
}
</script>

二、子传父

1、emit
// ------------------------------------------------父组件
<template>
  <div>父组件</div>
  <div>{{ money }}</div>
  <ChildPage @hander="chuli"></ChildPage>
</template>

<script setup lang="ts">
import ChildPage from '@/components/ChildPage.vue'
import { ref } from 'vue'

let money = ref(0)

const chuli = (num: number) => {
  money.value += num
}
</script>

// -----------------------------------------------子组件
<template>
  <div class="son">子组件</div>
  <button @click="toBa">传值给父组件</button>
</template>

<script setup lang="ts">
let emits = defineEmits(['hander'])
const toBa = () => {
  emits('hander', 10)
}
</script>
2、$parent
// ------------------------------------------------父组件
<template>
  <div>父组件</div>
  <div>{{ money }}</div>
  <ChildPage></ChildPage>
</template>

<script setup lang="ts">
import ChildPage from '@/components/ChildPage.vue'
import { ref } from 'vue'

let money = ref(10000)

const add = (num: number) => {
  money.value += num
}

//对外暴露
defineExpose({
  money,
  add
})
</script>


// -----------------------------------------------子组件
<template>
  <div class="dau">
    <h1>我是子组件</h1>
    <button @click="handler($parent)">点击我给父组件200元</button>
  </div>
</template>

<script setup lang="ts">
//子组件按钮点击回调
const handler = ($parent: any) => {
  $parent.money += 100
  $parent.add(100)
}
</script>

3、v-model

1、绑定一个

//-----------------------------------------------父组件
<template>
  <div>父组件</div>
  <div>{{ pageNo }}</div>
  <ChildPage v-model="pageNo"></ChildPage>
</template>

<script setup lang="ts">
import ChildPage from '@/components/ChildPage.vue'
import { ref } from 'vue'

//父亲的数据
let pageNo = ref(1)
</script>


//--------------------------------------------------子组件
<template>
  <div class="child2">
    <h1>绑定以个v-model</h1>
    <button @click="handler">pageNo{{ modelValue }}</button>
  </div>
</template>

<script setup lang="ts">
let props = defineProps(['modelValue'])
let $emit = defineEmits(['update:modelValue'])
//第一个按钮的事件回调
const handler = () => {
  $emit('update:modelValue', props.modelValue + 3)
}
</script>

2、绑定多个数据同步 

// -----------------------------------------父组件
<template>
  <div>父组件</div>
  <div>{{ pageNo }}-{{ pageSize }}</div>
  <ChildPage v-model:pageNo="pageNo" v-model:pageSize="pageSize"></ChildPage>
</template>

<script setup lang="ts">
import ChildPage from '@/components/ChildPage.vue'
import { ref } from 'vue'

//父亲的数据
let pageNo = ref(1)
let pageSize = ref(3)
</script>


// --------------------------------------------子组件
<template>
  <div class="child2">
    <h1>同时绑定多个v-model</h1>
    <button @click="handler">pageNo{{ pageNo }}</button>
    <button @click="$emit('update:pageSize', pageSize + 4)">pageSize{{ pageSize }}</button>
  </div>
</template>

<script setup lang="ts">
let props = defineProps(['pageNo', 'pageSize'])
let $emit = defineEmits(['update:pageNo', 'update:pageSize'])
//第一个按钮的事件回调
const handler = () => {
  $emit('update:pageNo', props.pageNo + 3)
}
</script>

三、全局组件通信

1、pinia

使用方法比较详细的写在了这篇文章:pinia使用方法-CSDN博客

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值