Vue3中组件间的数据传递【6】
组件间的数据传递
- 1.ref标签属性:
- 1.概述:
- 2.案例:
- 1.引用普通标签:
- 2.引用链接标签:
- 3.引用自定义标签:
- 2.子父组件之间的数据传递:
- 1.概述:
- 2.nanoid插件安装:
- 概述:
- 安装指令:
- 插件使用指南;
- 3.vue调试工具插件安装:
- 概述:
- 安装步骤:
- 4.父组件到子组件的数据传递:
- 案例分析:
- 代码案例:
- 案例分析:
- 结果测试:
- 3.vue3中的生命周期:
- 1.概述:
- 2.生命周期详解:
- 3.图解:
- 4.代码示例:
- 示例:
- 说明:
- 测试:
- 4.hook:
- 1.概述:
- 2.案例分析:
- 请求发送插件安装:
- 案例:
- 案例解析:
- 测试:
1.ref标签属性:
1.概述:
ref的标签属性表示在父组件(App)中给标签添加ref属性,作用是在父组件中添加对此自组件的引用,便于后面操作使用;
2.案例:
1.引用普通标签:
<template><h1 ref="title1">猿究院</h1><h1 ref="title2">Vue</h1><button @click="show">点击查看</button></template>
<script lang="ts" setup name="App">
import Temp from "./components/Temp.vue";
import { ref } from "vue";let title1=ref();
let title2=ref();
let show=()=>{//输出引用标签对象console.log(title1)console.log(title2)//输入引用标签的内置文本内容console.log(title1.value.innerText)console.log(title2.value.innerText)}
</script>
上述案例中,我们创建了两个普通标题标签,并在标签中添加ref属性,然后再脚本部分通过ref函数获取到这两个标签对象,注意标签对象的名称要与标签中ref属性的值一致;之后再单击鼠标时间的回调函数中输出了这两个标签对象及标签对象的内容文本内容;
2.引用链接标签:
<template><a ref="url" href="http://www.baidu.com">点我试试</a><button @click="show">点击查看</button></template>
<script lang="ts" setup name="App">
import Temp from "./components/Temp.vue";
import { ref } from "vue";
let url=ref();
let show=()=>{console.log(url)console.log(url.value.href)}
</script>
引用链接标签,获取此标签对象,之后在函数中输出该对象,及该对象的href属性
3.引用自定义标签:
<template><button @click="show">点击查看</button><Temp ref="temp"></Temp></template>
<script lang="ts" setup name="App">
import Temp from "./components/Temp.vue";
import { ref } from "vue";
let temp = ref();let show=()=>{console.log(temp)console.log(temp.value.temp)console.log(temp.value.height)
}
</script>
<template><h1>需求:水温与水位监测,当水温到50°C或者水位到20CM时,联系服务器</h1><h2>水温:{{ temp }}°C</h2><h2>水位:{{ height }}CM</h2><button @click="changeTemp">水温++</button><button @click="changeHeight">水位++</button>
</template><script lang="ts" setup name="WatchTemp">
import {ref, watch, watchEffect} from "vue";let temp = ref(40);
let height = ref(5);const changeTemp = () => {temp.value += 5;
}
const changeHeight = () => {height.value += 10;
}watchEffect(() => {//当温度与水位到预设值后if (temp.value >= 50 || height.value >= 20) {console.log("联系服务器")}
})
//父组件 尝试 获取 子组件的数据
//子组件需要暴露数据出来
defineExpose({temp,height})</script><style scoped></style>
上述案例中我们在父组件中引用了自定义子组件temp,并在子组件标签中添加ref属性,之后通过ref函数获取到子组件的标签对象,之后再show函数中输出了自定义标签对象,及自定义组件的两个数据temp和height;
注意:在子组件中必须通过defineExpose({要暴露的数据名})暴露出可被父组件访问的数据,否则父组件中无法获取到;
2.子父组件之间的数据传递:
1.概述:
在实际业务中,我们可能会经常面临一个场景,就是父子间与子组件之间进行数据传递,将当前组件的数据传递到其他组件中进行渲染展示;
2.nanoid插件安装:
概述:
此插件主要用于自动生成不重复的uuid,长度可以由我们自己选择,方便我们在业务中对于id属性的定义;
安装指令:
npm install nanoid
插件使用指南;
网址导航:[https://github.com/ai/nanoid/blob/main/README.zh-CN.md](https://github.com/ai/nanoid/blob/main/README.zh-CN.md)
3.vue调试工具插件安装:
概述:
此工具插件主要可将vue项目内容在浏览器上展示出来,<font style="color:rgba(0, 0, 0, 0.85);">你可以清晰地看到组件之间的嵌套关系,从根组件到各个子组件的层次一目了然。这对于理解大型复杂应用的架构非常有帮助。</font>
安装步骤:
1.极简插件官网导航:[https://chrome.zzzmh.cn](https://chrome.zzzmh.cn)2.进入官网后搜索vue.js3.选择路径下载并解压;4.打开浏览器右上角三个点,选择扩展程序--管理扩展程序5.将下载的插件拖到浏览器此页面,并启用
4.父组件到子组件的数据传递:
案例分析:
代码案例:
<template><!-- 传递 persons 给 Person组件 命名 为list --><Person :list="persons"></Person>
</template><script setup lang="ts" name="App">
import Person from "@/components/Person.vue";
import {reactive} from "vue";
import {nanoid} from 'nanoid'
import {type PersonInter, Persons} from "@/interface/IPerson";
//自定义数据 将数据准备传递给 子组件
let persons = reactive<Persons>([{id: nanoid(), name: '张三', age: 20},{id: nanoid(), name: '李四', age: 30},{id: nanoid(), name: '王武', age: 19}
])</script><style scoped></style>
export interface IPerson{id:string,name:string,age:number
}
export type persons=Array<IPerson>
<template><div class="person"><ul><li v-for="p in list":key="p.id">{{p.id}}--{{p.name}}--{{p.age}}</li></ul></div>
</template><script lang="ts" setup name="Person">import {defineProps, withDefaults} from "vue";import {persons} from "./interface/persons";
import {nanoid} from "nanoid";// 方式1:仅接收
// let props=defineProps(['list']);//方式2:接收并限制类型// defineProps<{list:persons}>();//方式3:接收并限制类型,并且有默认值,限制必要性
const props = withDefaults(defineProps<{ list: persons }>(), {list: () => [{id: nanoid(), name: '测试数据', age: 0}]
});</script><style scoped>.person{background-color: blueviolet;font-size: 20px;}
</style>
案例分析:
在上述案例中:
-
首先在App.vue(父组件)中准备一个对象数组,其中有三个对象数据。
-
其次在模板中引用person.vue(子组件),并在子组件标签中添加一个属性用于子组件接收数据。
-
定义persons.ts文件,在此文件中主要定义一个接口和自定义类型,用于规范父组件中的数据内容。
-
最后在子组件中接收父组件传递过来的数据,并在模板中进行渲染展示,接收的方式主要有以下三种:
-
方式1:defineProps(['list'])仅接收数据;
-
方式2:defineProps<{list:persons}>();接收数据,并通过定义的类型来规范接收数据的内容;
-
方式3:withDefaults(defineProps<{ list: persons }>(), {list: () => [{id: nanoid(), name: '测试数据', age: 0}]});接收数据并规范数据内容以及提供默认值和限制必要性;
结果测试:
测试1:数据正常传递
测试2:展示默认数据
3.vue3中的生命周期:
1.概述:
在vue3中的生命周期与vue2中的类似,主要也分为创建阶段,挂载阶段,更新阶段和销毁阶段四部分。不同点在于vue3中有setup函数的存在,此函数会在创建阶段的两个钩子函数之前执行;
2.生命周期详解:
-
执行setup函数;
-
创建阶段:
-
beforeCreate():创建之前,无数据,方法
-
created():创建之后,有数据,方法,无DOM元素
-
挂载阶段:
-
beforeMount():虚拟DOM生成,无真实DOM,页面上无渲染内容
-
mounted():真实DOM生成,并页面渲染完成
-
更新阶段:
-
beforeupdate():数据已更新,页面未渲染
-
updated(): 数据更新,并且页面同步渲染
-
销毁阶段:
-
beforeUnmount():卸载之前
-
unmounted():卸载之后
3.图解:
4.代码示例:
示例:
<template><h2>Count:{{count}}</h2><button @click="changeCount">count++</button>
<!-- <button @click="" >销毁相关操作按钮</button>-->
</template>
<script lang="ts" setup name="Test">
import {onBeforeMount, onBeforeUnmount, onBeforeUpdate, onMounted, onUnmounted, onUpdated, ref} from "vue";console.log('setup函数及onBeforeCreate,onCreate函数执行了')
let count = ref(0);
const changeCount = () => {count.value++;
};onBeforeMount(() => {console.log('挂载之前执行:BeforeMount');
});
onMounted(() => {console.log('挂载之后执行:Mounted');
});
onBeforeUpdate(() => {console.log('更新前执行:beforeupdate');
});
onUpdated(() => {console.log('更新之后执行:updated');
});
onBeforeUnmount(() => {console.log('卸载之前执行:BeforeUnmount');
});
onUnmounted(() => {console.log('卸载之后执行:Unmounted');
});
</script>
<style scoped>
</style>
说明:
上述案例中,我们在setup函数中调用了vue3中各阶段的钩子函数,来模拟各阶段的狗子函数的执行情况;
注意:
-
在setup语法糖中无法调用创建阶段的两个钩子函数,因为功能重复了,但这两个函数会自行执行;
-
vue3中的销毁无法通过像vue2中的方式实现,因为在vue3中的销毁是由vue3自行处理,无法通过事件手动触发,故未进行模拟;
测试:
测试1:页面正常渲染;
测试2:修改数据,触发更新阶段的钩子函数;
4.hook:
1.概述:
在 Vue 3 中,Hook(钩子函数)是一种用于在组件生命周期的不同阶段执行特定逻辑的函数机制。它类似于 Vue 2 中的生命周期函数,但在 Vue 3 中,通过组合式 API(Composition API)来实现,更加灵活和可复用。
除了使用 Vue 3 提供的内置 Hook,还可以创建自定义 Hook。自定义 Hook 是将组件中可复用的逻辑提取出来,形成独立的函数,实现函数的封装。
2.案例分析:
请求发送插件安装:
在下面案例中我们需要向服务器发送请求,但此时项目不支持请求发送,因此我们需要安装一个插件axios;
npm i axios
案例:
import {onMounted, ref} from "vue";export default function (){let sum=ref(6);const increment=()=>{sum.value+=1;}const decrement=()=>{sum.value-=1;}onMounted(()=>{increment();})return{sum,increment,decrement}
}
import {onMounted, reactive} from "vue";
import axios from "axios";
export default function (){let dogList=reactive([]);function getDog(){//发生请求:axios.get('https://dog.ceo/api/breed/pembroke/images/random').then(res => {//请求成功 res.data 返回结果console.log(res.data)dogList.push(res.data);}).catch(error=>{console.log("请求错误", error.message)}).finally(()=>{console.log('一定执行的内容')})}onMounted(()=>{getDog()})return{dogList,getDog}
}
<template><h2>Sum:{{sum}}</h2><button @click="increment">sum++</button><button @click="decrement">sum--</button><hr/><button @click="getDog">再来一只</button><br/><img style="width: 100px;height: 100px;" v-for="(dog,index) in dogList" :key="index" :src="dog.message"></template><script lang="ts" setup name="myTest">import UserSum from "./ts/UserSum";import useDog from "./ts/useDog";let{sum,increment,decrement}=UserSum();let{dogList,getDog}=useDog();
</script><style scoped></style>
<template><MyTest></MyTest>
</template><script setup lang="ts" name="App">
import MyTest from "@/components/MyTest.vue";
</script>
<style scoped></style>
案例解析:
在上述案例中:
-
首先自定义两个模块(ts文件)其中包含一些数据和函数;
-
其次在子组件myTest中导入两个ts文件,并通过解构解析获取到ts文件中的数据和函数;
-
之后再此子组件的模板中获取数据及将ts文件中的函数绑定到单击事件上
-
最后将子组件导入父组件App.vue中,实现页面的渲染;
测试:
测试1:页面正常渲染
测试2:单击sum++按钮
测试3:单击sum–按钮
测试4:单击’再来一只’按钮’