当前位置: 首页 > news >正文

《Vue3学习手记7》

组件通信(续)

$attrs

组件通信:$attrs 适用于祖传孙孙传祖 (需要通过中间组件)
传递给后代的数据,但未被接收,都保存在attrs中

1.祖传孙

父组件:

<template><div class="father"><h3>父组件</h3><h3>a:{{ a }}</h3><h3>b:{{ b }}</h3><h3>c:{{ c }}</h3><Child :a="a" :b="b" :c="c"/>  <!-- 1.1.传递给儿子 --></div>
</template><script setup lang="ts" name="Father">import Child from './Child.vue'import {ref} from 'vue'let a=ref(1)let b=ref(2)let c=ref(3)// 2.使用attrs实现孙传祖let gift=ref("")// 2.1 getGift函数function getGift(value:string){gift.value=value}// 使用mitt实现孙传祖// let gift=ref("")// emitter.on("getGift",(value:string)=>{// 	gift.value=value// })
</script>

子组件:

<template><div class="child"><h3>子组件</h3><GrandChild v-bind="$attrs"/>  <!-- 1.2.儿子将父亲传递过来但未被接收的数据传给孙子 --></div>
</template><script setup lang="ts" name="Child">import GrandChild from './GrandChild.vue'
</script>

孙组件:

<template><div class="grand-child"><h3>孙组件</h3><h3>a:{{ a }}</h3><h3>b:{{ b }}</h3><h3>c:{{ c }}</h3></div>
</template><script setup lang="ts" name="GrandChild">
import {ref} from "vue"
const gift=ref("飞机")// 1.3 孙子接收数据defineProps(["a","b","c"])  //1.4 注意接收的内容
</script>

2.孙传祖

父组件:

<template><div class="father"><h3>父组件</h3><h3>a:{{ a }}</h3><h3>b:{{ b }}</h3><h3>c:{{ c }}</h3><Child :a="a" :b="b" :c="c" :getGift="getGift"/> <-- 2.2 将getGift函数传递过去--><hr><h2>得到孙子给的礼物:{{ gift }}</h2></div>
</template><script setup lang="ts" name="Father">import Child from './Child.vue'import {ref} from 'vue'let a=ref(1)let b=ref(2)let c=ref(3)// 2.使用attrs实现孙传祖let gift=ref("")// 2.1 getGift函数function getGift(value:string){gift.value=value}
</script>

子组件:

<template><div class="child"><h3>子组件</h3><GrandChild v-bind="$attrs"/>  <!-- 1.2.儿子将父亲传递过来但未被接收的数据传给孙子 --></div>
</template>

孙组件:

<template><div class="grand-child"><h3>孙组件</h3><h3>a:{{ a }}</h3><h3>b:{{ b }}</h3><h3>c:{{ c }}</h3><hr><h4>礼物:{{gift}}</h4><button @click="getGift(gift)">点我将礼物给爷爷</button></div>
</template><script setup lang="ts" name="GrandChild">
import {ref} from "vue"
const gift=ref("飞机")// 1.3.孙子接收数据defineProps(["a","b","c","getGift"])  //1.4注意接收的内容
// 2.3使用attrs实现孙传祖--接收传递过来的函数getGift
</script>

$refs和 $parent

先使用ref进行通信:
父组件:

<template><!-- 组件通信:$refs父传子和$parents子传父 --><!-- 知识点1:ref --><div class="father"><h3>父组件</h3><h2>房子:{{ house }}</h2><h2>财产:{{ money }}</h2><button @click="sendMoney">点击修改儿子1玩具为奥特曼</button><Child1 ref="ch1"/><Child2 ref="ch2"/></div>
</template><script setup lang="ts" name="Father">import Child1 from './Child1.vue'import Child2 from './Child2.vue'import { ref,reactive } from "vue";const house=ref(3)const money=ref(300)// 1.数据const ch1=ref()const ch2=ref()// 2.方法:function sendMoney(){ch1.value.toy="奥特曼"} 
</script>

子组件:

<template><div class="child1"><h3>子组件1</h3><h2>书籍:{{ book }}</h2><h2>玩具:{{toy}}</h2></div>
</template><script setup lang="ts" name="Child1">import { ref } from "vue";const book=ref(4)const toy=ref("乐高")// 3.defineExpose({toy})   //注意!里面是{},不是[]
</script>

$refs 父传子

父组件:

<template><!-- 组件通信:$refs父传子和$parents子传父 --><!-- 知识点1:ref --><div class="father"><h3>父组件</h3><h2>房子:{{ house }}</h2><h2>财产:{{ money }}</h2><button @click="getAll($refs)">获取所有子组件的实例对象</button>  <!-- 获取到所有打了ref标识的组件的实例对象 --><Child1 ref="ch1"/><Child2 ref="ch2"/></div>
</template><script setup lang="ts" name="Father">import Child1 from './Child1.vue'import Child2 from './Child2.vue'import { ref,reactive } from "vue";const house=ref(3)const money=ref(300)//***********************************************************************************
// 知识点二:当有很多子组件都需要修改,那就要写很多代码,可以使用$refs获得所有组件实例对象// $refsfunction getAll(refs:object){// console.log(refs)// 将child1和2的书籍增加两本// 遍历  (遍历数组用index索引值,遍历对象用key)for (let key in refs){// console.log(key)   //输出ch1和ch2// console.log(refs[key])refs[key].book+=2}}
</script>

子组件:

//子组件1:
defineExpose({toy,book})   
//子组件2:
defineExpose({book}) 

$parent 子传父

子组件:

<template>
<!-- 知识点三:子传父$parent --><button @click="reduceMoney($parent)">点我父亲资产减10</button>
</template><script setup lang="ts" name="Child1">import { ref } from "vue";const book=ref(4)const toy=ref("乐高")// ***********************************3.1 function reduceMoney(parent:any){  //"parent"自己定义// console.log(parent)    //得到的就是父组件defineExpose的数据parent.money-=10}
</script>

父组件:

// 3.2 defineExpose({money})

provide和inject

组件通信:provide和inject祖孙通信。
和attrs区别在于:不用使用中间组件而attrs需要使用中间组件

祖组件:

祖——孙

<template>组件通信:provide和inject祖孙通信。和attrs区别在于:不用使用中间组件而attrs需要使用中间组件 <div class="father"><h3>父组件</h3><h2>房子:{{ house }}</h2><h2>财产:{{ money }}</h2><Child/></div>
</template><script setup lang="ts" name="Father">import Child from './Child.vue'import {ref,reactive,provide,inject} from 'vue'const house=ref(3)const money=ref(300)// 1.2 爷爷传递数据给孙子provide("money",money)  //第一个money可自定义
</script>

孙组件:

<template><div class="grand-child"><h3>我是孙组件</h3><h2>书籍:{{ book }}</h2><h2>玩具:{{toy}}</h2><h2>得到爷爷的money:{{ money }}</h2></div>
</template><script setup lang="ts" name="GrandChild">import {ref} from "vue"import {provide,inject} from "vue"const book=ref(4)const toy=ref("乐高")// *****************************************************// 知识点一:祖-孙,实现爷爷向孙子通信(传递数据)// 1.1 得到爷爷传过来的数据let money=inject("money",0)//第二个参数是默认值
</script>

孙——祖
祖组件:

 // 2.1定义一个函数function changeMoney(value:number){money.value-=value}// 2.2提供changeMoney函数provide("moneyText",{money,changeMoney}) //提供多个内容用对象形式

孙组件:

 <button @click="changeMoney(2)">点我修改爷爷的money</button>// 知识点二:孙-祖,实现孙子向爷爷通信(传递数据)// 2.3注入let {money,changeMoney}=inject("moneyText",0)

pinia

可以参考前边对pinia的理解

slot插槽

组件通信:slot-父组件向子组件传递模板内容

默认插槽

数据在父组件
父组件:

<template><div class="father"><Category title="今日游戏推荐"><ul><li v-for="(g,id) in games" :key="id">{{ g.name }}</li></ul></Category><Category title="今日美食推荐"><img :src="img" alt=""></Category><Category title="今日视频推荐"><video :src="video"></video></Category></div>
</template><script setup lang="ts" name="Father">
import Category from './Category.vue';
import {ref,reactive} from 'vue'
let games = reactive([{id:'asgytdfats01',name:'英雄联盟'},{id:'asgytdfats02',name:'王者农药'},{id:'asgytdfats03',name:'红色警戒'},{id:'asgytdfats04',name:'斗罗大陆'}])const img=ref("https://z1.ax1x.com/2023/11/19/piNxLo4.jpg")const video=ref("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
</script>

子组件:

<template><div class="game"><h2>{{title}}</h2><slot>如果没有内容展示就显示默认内容</slot><!-- 等同于: --><!-- <slot name="default"></slot> --></div>
</template><script setup lang="ts" name="Game">
defineProps(["title"])
</script>

具名插槽

数据在父组件
父组件:
实现h2标题在内容下——一般用于内容展示和模板中的顺序不一样,使用template标签

<template><div class="father"><Category><template v-slot:two>   <!-- 注意!这里不是= --><h2>今日游戏推荐</h2></template><template v-slot:one><ul><li v-for="(g,id) in games" :key="id">{{ g.name }}</li></ul></template></Category><Category><template #two>   <!-- 简写 --><h2>今日美食推荐</h2></template><template #one>   <img :src="img" alt=""></template></Category><Category><template v-slot:two>   <h2>今日视频推荐</h2></template><template v-slot:one>   <video :src="video"></video></template></Category></div>
</template><script setup lang="ts" name="Father">
import Category from './Category.vue';
import {ref,reactive} from 'vue'
let games = reactive([{id:'asgytdfats01',name:'英雄联盟'},{id:'asgytdfats02',name:'王者农药'},{id:'asgytdfats03',name:'红色警戒'},{id:'asgytdfats04',name:'斗罗大陆'}])const img=ref("https://z1.ax1x.com/2023/11/19/piNxLo4.jpg")const video=ref('http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4')
</script>

子组件:

<template><div class="game"><h2>{{title}}</h2><slot name="one">如果没有内容展示就显示默认内容</slot><slot name="two"></slot></div>
</template><script setup lang="ts">
defineProps(["title"])</script>

作用域插槽

父组件:
数据在子组件

<template><!-- 作用域插槽 --><div class="father"><Category><template v-slot:two>   <!-- 注意!这里不是= --><h2>今日游戏推荐</h2></template><template v-slot:one="params"><ul><li v-for="(g,id) in params.games" :key="id">{{ g.name }}</li></ul></template></Category><Category><template #two>   <!-- 简写 --><h2>今日美食推荐</h2></template><template #one="params">   <img :src="params.image" alt=""></template></Category><Category><template v-slot:two>   <h2>今日视频推荐</h2></template><template v-slot:one="params">   <video :src="params.video"></video></template></Category></div>
</template><script setup lang="ts" name="Father">
import Category from './Category.vue';
</script>

子组件:

<template><div class="game"><h2>{{title}}</h2><slot name="one" :games="games" :image="img" :video="video">如果没有内容展示就显示默认内容</slot><slot name="two"></slot></div>
</template><script setup lang="ts">
defineProps(["title"])
import {ref,reactive} from 'vue'
let games = reactive([{id:'asgytdfats01',name:'英雄联盟'},{id:'asgytdfats02',name:'王者农药'},{id:'asgytdfats03',name:'红色警戒'},{id:'asgytdfats04',name:'斗罗大陆'}])const img=ref("https://z1.ax1x.com/2023/11/19/piNxLo4.jpg")const video=ref('http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4')
</script>
http://www.xdnf.cn/news/212293.html

相关文章:

  • RVO2(C#版)源码分析
  • 什么是ICSP编程
  • [展示]集成式深度学习对音频降噪的基准测试BenchMark
  • 【图片识别改名】批量读取图片区域文字识别后批量改名,基于Python和腾讯云的实现方案
  • [随笔] 升级uniapp旧项目的vue、pinia、vite、dcloudio依赖包等
  • BG开发者日志429:故事模式的思路
  • Mac 创建QT按钮以及一些操作
  • iVX 可视化调试:重塑 AI 编程规则的变革
  • 【11408学习记录】考研英语语法核心:倒装句考点全解+真题演练
  • 如何用vivado导出pin delay
  • 第33周JavaSpringCloud微服务 多人协作下的调试
  • CSRF(cross-site request forgery)跨域请求访问
  • Reverse-WP记录9
  • 51la统计坏了吗?用悟空统计保障运营决策安全详解
  • 斯坦福课程 MSE 318/CME 338: Large-Scale Numerical Optimization
  • Linux权限拓展
  • Headers池技术在Python爬虫反反爬中的应用
  • Kotlin 常见问题
  • 简单音频比较
  • 数据库day-08
  • C#中winform窗体如何捕获键盘按键事件
  • 深度学习篇---模型权重变化与维度分析
  • 阿里云 OpenManus 实战:高效AI协作体系
  • “情况说明“以后,Unity XR 开发者如何选择?
  • HTTP(超文本传输协议)全面总结
  • 蓝桥杯 10. 凯撒加密
  • [C]基础14.字符函数和字符串函数
  • 网络原理—应用层和数据链路层
  • 指针(5)
  • Spring Boot 集成 ActiveMQ 实现异步消息通信(一)