概述
组件通信是前端开发技术中的核心,上节讲到使用props、自定义事件、mitt、v-model组件通信方法,其他五中通信方式:
- $attrs
- ref
- parent
- provide、inject
- pinia
$attrs组件通信方式
概述
attrs给孙,孙再接收props
- 创建App,传递props数据name,price
- 创建Fish,不收接props数据,使用v-bind传递$attrs
- 创界FishDetail,接收props数据
事例代码
App组件代码
<template>
<div class="app">
<h2>祖组件鱼:{{ name }}</h2>
<h2>祖组件价格:{{ price }}</h2>
<h2>祖组件数量:{{ num }}</h2>
<Fish :name="name" :price="price" :changeFish="changeFish"/>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import Fish from './view/Fish.vue';
let name = ref('鲫鱼');
let price = ref(666);
let num = ref(0);
function changeFish(val: number) {
num.value = val;
}
Fish组件代码
<template>
<div>
<h2>子组件</h2>
<FishDetail v-bind="$attrs"/>
</div>
</template>
<script setup lang="ts">
import FishDetail from './FishDetail.vue';
</script>
FishDetail组件代码
<template>
<div>
<h2>孙组件鱼类:{{ name }}</h2>
<h2>孙组件价格:{{ price }}</h2>
<h2>孙组件数量:{{ num }}</h2>
<button @click="changeFish(++num)">修改鱼的数据</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
let num = ref(666);
let props = defineProps(['name','price','changeFish']);
</script>
运行效果
$ref组件通信
概述
$ref获取组件实例,只能由父组件获取子组件数据。父组件获取子组件实例对象后,通过实例对象操作子组件声明的数据
$ref组件通信事例
App组件代码
<template>
<div class="app">
<button @click="changeFish()">修改子组件数据</button>
<Fish ref="fish"/>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import Fish from './view/Fish.vue';
let fish = ref();
function changeFish() {
fish.value.price++;
}
</script>
Fish组件代码
<template>
<div>
<h2>子组件{{name}}</h2>
<h2>子组件{{price}}</h2>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
let name = ref('鲫鱼');
let price = ref(0);
defineExpose({ price });
</script>
运行实例代码
$parent组件通信
ref刚好相反,它是子到父,子获取父的数据。
- 创建父组件App,定义数据name,price
- 父组件App暴露数据,price
- 创建子组件Fish,通过$parent变量获取price App组件代码
<template>
<div class="app">
<h2>父组件{{name}}</h2>
<h2>父组件{{price}}</h2>
<Fish/>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import Fish from './view/Fish.vue';
let name = ref('鲫鱼');
let price = ref(999);
defineExpose({ price })
</script>
FIsh组件代码
<template>
<div>
<button @click="changeFish($parent)">修改子组件数据</button>
</div>
</template>
<script setup lang="ts">
function changeFish(parent: any) {
parent.price++
}
</script>
provide、inject组件通信
概述
provide、inject组件通信是实现父组件向其后代传递数据的一种方式,任何一个后代需要数据,就可以接收处理。
provide、inject组件通信事例
- 创建祖组件App,创建数据name,price,函数changeFish,provide数据与函数
- 创建父组件Fish,不做接收
- 创建子组件FishDetail,inject数据与函数 App组件代码
<template>
<div class="app">
<h2>父组件{{name}}</h2>
<h2>父组件{{price}}</h2>
<Fish/>
</div>
</template>
<script setup lang="ts">
import { provide, ref } from 'vue';
import Fish from './view/Fish.vue';
let name = ref('鲫鱼');
let price = ref(999);
provide('name',name);
provide('price', price);
provide('changeFish', changeFish);
function changeFish(num: any) {
name.value+='~'
price.value += num;
}
</script>
Fish组件代码
<template>
<FishDetail/>
</template>
<script setup lang="ts">
import FishDetail from './FishDetail.vue';
</script>
FishDetail组件代码
<template>
<div>
<h2>孙组件{{name}}</h2>
<h2>孙组件{{price}}</h2>
<button @click="changeFish(10)">修改祖组件数据</button>
</div>
</template>
<script setup lang="ts">
import { inject } from 'vue';
let name=inject('name');
let price=inject('price');
let changeFish = inject('changeFish', (num: number) => { });
</script>
注意这行代码,
let changeFish = inject('changeFish', (num: number) => { });第二个参数是默认值,提供一个默认函数。