Vue3 组件通信
文章目录
学习总结
props
rops是使用频率最高的一种通信方式,常用于:父<->子
● 若父传子:属性值是非函数
● 若子传父:属性值是函数
<div class="father">
<h3>父组件</h3>
<h4>汽车:{{ car }}</h4>
<h4 v-show="toy">子给父的玩具:{{ toy }}</h4>
<Child :car="car" :sendToy="getToy"></Child>
</div>
import Child from './Child.vue';
import { ref } from 'vue';
let car = ref('奔驰')
let toy = ref('')
function getToy(value: string) {
toy.value = value
}
</script>
<style lang="scss" scoped>
.father {
width: 100%;
background-color: pink;
}
<div class="child">
<h3>子组件</h3>
<h4>玩具:{{ toy }}</h4>
<h4>父给的车:{{ car }}</h4>
<button @click="sendToy(toy)">把玩具给父亲</button>
</div>
import { ref } from 'vue'
let toy = ref('奥特曼')
defineProps(['car', 'sendToy'])
自定义事件
<div class="father">
<h3>父组件</h3>
<h4 v-show="toy">子给父的玩具:{{ toy }}</h4>
<Child @send-toy="saveToy"></Child>
</div>
import Child from './Child.vue';
import { ref } from 'vue';
let toy = ref('')
function saveToy(value:string){
console.log('saveToy',value);
toy.value = value
}
<div class="child">
<h3>子组件</h3>
<h4>玩具:{{ toy }}</h4>
<button @click="emit('send-toy',toy)">测试</button>
</div>
import { ref } from 'vue'
let toy = ref('小汽车')
const emit = defineEmits(['send-toy'])
mitt(全局事件总线)
安装
npm install --save mitt
基本使用
// 引入
import mitt from 'mitt'
// 调用mitt得到emitter,emitter能绑定事件、触发事件
const emitter = mitt()
emitter.on('test1', ()=>{
console.log('test1调用');
})
emitter.on('test2', () => {
console.log('test2调用');
})
// 触发事件
setInterval(()=>{
emitter.emit('test1')
emitter.emit('test2')
},1000)
setTimeout(()=>{
emitter.all.clear()
},5000)
// 暴露emitter
export default emitter
v-model
1. 单个数据绑定
<Child v-model="money"></Child>
2. 多个数据绑定
<Child1 v-model:pageNo="pageNo" v-model:pageSize="pageSize"></Child1>
//父亲的数据
let pageNo = ref(1)
let pageSize = ref(3)
<div class="child2">
<h1>同时绑定多个v-model</h1>
<button @click="handler">pageNo{{ pageNo }}</button>
<button @click="$emit('update:pageSize', pageSize + 4)">
pageSize{{ pageSize }}
</button>
</div>
let props = defineProps(["pageNo", "pageSize"]);
let $emit = defineEmits(["update:pageNo", "update:pageSize"]);
//第一个按钮的事件回调
const handler = () => {
$emit("update:pageNo", props.pageNo + 3);
};
$attrs
- 概述:$attrs用于实现当前组件的父组件,向当前组件的子组件通信(祖->孙)
- 具体说明:$ attrs是一个对象,包含所有父组件传入的标签属性,
注意:$attrs会自动排除props中声明的属性(可以认为声明过的props被子组件自己“消费了”)
<div class="father">
<h3>父组件</h3>
<h4>a: {{ a }}</h4>
<h4>b: {{ b }}</h4>
<h4>c: {{ c }}</h4>
<h4>d: {{ d }}</h4>
<Child :a="a" :b="b" :c="c" :d="d" :updateA="updateA"></Child>
</div>
import Child from './Child.vue';
import { ref } from 'vue';
let a = ref(1)
let b = ref(2)
let c = ref(3)
let d = ref(4)
function updateA (value:number) {
a.value += value
}
<div class="child">
<h3>子组件</h3>
<h4>其他:{{ $attrs }}</h4>
<GrandChild v-bind="$attrs"></GrandChild>
</div>
import { ref } from 'vue'
import GrandChild from './GrandChild.vue';
<div class="grand-child">
<h3>孙组件</h3>
<h4>a: {{ a }}</h4>
<h4>b: {{ b }}</h4>
<h4>c: {{ c }}</h4>
<h4>d: {{ d }}</h4>
<button @click="updateA(6)">点我爷爷那a更新</button>
</div>
defineProps(['a','b','c','d','updateA'])
ref与$parent
1. ref
获取真实的DOM节点,可以获取到子组件实例VC,在父组件中拿到子组件的实例,那么就可以操作子组件的属性及方法了,默认情况下是拿不到的,子组件需要对外暴露才行
<template>
<div class="father">
<h3>父组件</h3>
<h4>房产:{{ house }}</h4>
<button @click="changeToy">修改child的玩具</button>
<Child ref="c1"></Child>
<Child2></Child2>
</div>
</template>
<script setup lang="ts" name="Father">
import Child from './Child.vue';
import Child2 from './Child2.vue';
import { ref } from 'vue';
let c1 = ref()
let house = ref(4)
function changeToy() {
c1.value.toy = '小球'
console.log(c1.value);
}
</script>
<template>
<div class="child">
<h3>子组件</h3>
<h4>玩具:{{ toy }}</h4>
<h4>书:{{ book }}本</h4>
</div>
</template>
<script setup lang="ts" name="Child">
import { ref } from 'vue'
let toy = ref('奥特曼')
let book = ref(3)
// 组件内部数据对外关闭的,别人不能访问,如果想外部访问需要通过defineExpose方法对外暴露
defineExpose({ toy, book })
</script>
<style lang="scss" scoped>
.child {
width: 80%;
background-color: sandybrown;
border: 1px solid rgb(252, 153, 66);
}
</style>
2. $parent获取父组件实例对象
<Dau></Dau>
<script setup lang="ts">
//$parent:可以在子组件内部获取到父组件的实例
//引入子组件
import Dau from './Daughter.vue'
import { ref } from 'vue'
//父组件钱数
let money = ref(100000000)
//对外暴露
defineExpose({
money
)}
</script>
<template>
<div class="dau">
<h1>我是子组件{{money}}</h1>
<button @click="handler($parent)">点击我父组件给我10000元</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
//子组件钱数
let money = ref(999999)
//子组件按钮点击回调
const handler = ($parent: any) => {
console.log($parent)
money.value += 10000
$parent.money -= 10000
}
</script>
provide-inject 实现隔辈传输
父组件:用provide传输对应的数据,并提供一个key,后续的子组件在拿数据也是根据此key
<template>
<div class="box">
<h1>Provide与Inject{{car}}</h1>
<hr />
<Child></Child>
</div>
</template>
<script setup lang="ts">
import Child from "./Child.vue";
//vue3提供provide(提供)与inject(注入),可以实现隔辈组件传递数据
import { ref, provide } from "vue";
let car = ref("法拉利");
//祖先组件给后代组件提供数据
//两个参数:第一个参数就是提供的数据key
//第二个参数:祖先组件提供数据
provide("TOKEN", car);
</script>
子组件:使用inject和对应的key获取到对应的数据
<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>
下周总结
项目项目项目,专业课专业课专业课
原文地址:https://blog.csdn.net/2302_80244686/article/details/143664982
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!