Vue3(三):生命周期、路由、自定义hooks

这里终于明白了为什么一直有这个语法报错,就是在提示你哪里错的地方上方注释一行/*eslint-disable*/,之前一直警告这个错误感谢老师! 

一、vue2和vue3生命周期 

还有一个问题就是父组件和子组件哪个先挂载完毕呢?答案是子组件先挂载完毕。因为首先解析入口文件index.html=>main.ts=>App.vue=>Person.vue,所以当然是Person.vue先挂载完毕,才能继续解析App.vue。 

  <template><div class="person"><h2>当前求和为:{{ sum }}</h2><button @click="changeSum">点我sum+1</button></div></template><!-- vue3写法 --><script lang="ts" setup name="Person">import { ref, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted } from 'vue'// 数据let sum = ref(0)// 方法function changeSum() {sum.value += 1}console.log('setup')// 生命周期钩子onBeforeMount(()=>{console.log('挂载之前')})onMounted(()=>{console.log('挂载完毕')})onBeforeUpdate(()=>{console.log('更新之前')})onUpdated(()=>{console.log('更新完毕')})onBeforeUnmount(()=>{console.log('卸载之前')})onUnmounted(()=>{console.log('卸载完毕')})</script>

二、自定义hooks 

hook本质是一个函数,用use开头,把setup函数中使用的Composition API进行了封装。可以更方便我们去复用处理数据的逻辑.

有时候我们会写很多数据和方法,如果都写在Person.vue会很大很复杂也不好修改,所以我们可以在src下新建hooks文件夹 ,建立useDog.ts和useSum.ts,拆分Person.vue中的东西。

例如:

Person.vue

<template><div class="person"><h2>当前求和为:{{ sum }},放大十倍{{ bigSum }}</h2><button @click="add">点我sum+1</button><hr><img v-for="(dog,index) in dogList" :src="dog" :key="index"><hr><button @click=" getDog">再来一只小狗</button></div>
</template><script lang="ts" setup name="Person">import useSum from '@/hooks/useSum'import useDog from '@/hooks/useDog'let { sum,add,bigSum} = useSum()let { dogList, getDog } = useDog()
</script><style scoped>
.person {background-color: skyblue;border-radius: 0 0 10px;box-shadow: 10px;padding: 10px;
}
button {margin: 5px;
}
img{height: 100px;
}
</style>

useDog.ts

import { reactive, onMounted } from 'vue';
import axios from 'axios';export default function () {//数据let dogList = reactive(['https://images.dog.ceo/breeds/pembroke/n02113023_4373.jpg',]);//方法async function getDog() {try {let result = await axios.get('https://dog.ceo/api/breed/pembroke/images/random');dogList.push(result.data.message);} catch (error) {alert(error);}}//钩子onMounted(() => {getDog();//千万别忘了在上面引入onMounted});//向外部提供数据return { dogList, getDog };
}

useSum.ts

import { ref,onMounted,computed } from 'vue';export default function () {//数据let sum = ref(0);let bigSum = computed(()=>{return sum.value*10})//方法function add() {sum.value += 1;}//钩子onMounted(()=>{add()})//向外传输return {sum,add,bigSum}
}

效果:

但是可能遇到如下报错,'xxx' is never reassigned.use 'const' instead prefer-const,解决办法如下: 

三、路由 

1.理解:

2.路由的基本切换

其实大致和vue2是差不多的,

(1)首先要下载vue-router的依赖

(可能有些在创建项目的时候就已经选择了要配置router,那么这时候就不要下载了,可以去packge.json中查看自己的vue-router版本号如果有的话就不用下载了)

npm install vue-router@4(后面可以指定版本,或者不@直接下载就是最新版本)

 (2)在src目录下新建一个router目录,在router目录下新建一个index.ts文件

//创建一个路由器并暴露粗去//第一步:引入
import { createRouter, createWebHistory } from 'vue-router';
//引入一个个要呈现的组件
import Home from '../pages/Home.vue';
import News from '../pages/News.vue';
import About from '../pages/About.vue';//第二步:创建路由器
const router = createRouter({history: createWebHistory(),//路由器的工作模式routes: [//引入路由规则{path: '/home',component: Home,},{path: '/news',component: News,},{path: '/about',component: About,},],
});
export default router;

createRouter函数,新建一个路由器;

createWebHistory函数可以创建一个 HTML5 History 路由实例,从而能够支持浏览器的前进和后退按钮。

routes:存放一个一个的路由;在这里每一个路由都是一个对象,必须要指定的由两个参数:

path:指定路由的路径

component:指定路由对应的组件

(3)在main.ts中引入路由

import { createApp } from "vue"
import APP from './App.vue'
//引入路由
import router from './router'
//创建一个应用
const app = createApp(APP)
// 使用路由器
app.use(router)
//挂载整个应用到app中
.mount('#app')

(4)实现路由的跳转

在App.vue中这样写,利用RouterLink导航 和to=""路径active-class=""实现点哪哪亮效果

RouterLink标签会被渲染成一个 <a> 标签,点击它时会触发路由切换。

RouterView 标签是展示区,会根据当前路由的路径自动加载对应的组件,并将其渲染到页面中。

<template><div class="app"><h2 class="title">Vue路由测试</h2><!-- 导航区 --><div class="navigate"><RouterLink to="/home" active-class="xiaozhupeiqi">首页</RouterLink><RouterLink to="/news" active-class="xiaozhupeiqi">新闻</RouterLink><RouterLink to="/about" active-class="xiaozhupeiqi">关于</RouterLink></div><!-- 展示区 --><div class="main-content"><RouterView></RouterView></div></div>
</template><script lang="ts" setup name="App">
import { RouterView, RouterLink } from 'vue-router'</script><style>
/* App */
.title {text-align: center;word-spacing: 5px;margin: 30px 0;height: 70px;line-height: 70px;background-image: linear-gradient(45deg, gray, white);border-radius: 10px;box-shadow: 0 0 2px;font-size: 30px;
}.navigate {display: flex;justify-content: space-around;margin: 0 100px;
}.navigate a {display: block;text-align: center;width: 90px;height: 40px;line-height: 40px;border-radius: 10px;background-color: gray;text-decoration: none;color: white;font-size: 18px;letter-spacing: 5px;
}.navigate a.xiaozhupeiqi {background-color: #64967E;color: #ffc268;font-weight: 900;text-shadow: 0 0 1px black;font-family: 微软雅黑;
}.main-content {margin: 0 auto;margin-top: 30px;border-radius: 10px;width: 90%;height: 400px;border: 1px solid;
}</style>

(5)pages中的静态页面 

 分别有Home.vue,About.vue,News.vue 这里不再写明,可以去老师的笔记里面自取

(6)效果

3.两个注意点

4.两种工作模式

1. history模式

    优点:`URL`更加美观,不带有`#`,更接近传统的网站`URL`。

   缺点:后期项目上线,需要服务端配合处理路径问题,否则刷新会有`404`错误。

//创建一个路由器并暴露粗去//第一步:引入
import { createRouter, createWebHistory } from 'vue-router';
//引入一个个要呈现的组件
import Home from '../pages/Home.vue';//第二步:创建路由器
const router = createRouter({history: createWebHistory(),//路由器的工作模式historyroutes: [//引入路由规则{path: '/home',component: Home,}],
});
//暴露出去
export default router;

2. hash模式

 优点:兼容性更好,因为不需要服务器端处理路径。

 缺点:`URL`带有`#`不太美观,且在`SEO`优化方面相对较差。

 const router = createRouter({history:createWebHashHistory(), //hash模式/******/})

 5.to的两种写法

 字符串写法和对象写法

<!-- 第一种:to的字符串写法 -->
<router-link active-class="active" to="/home">主页</router-link><!-- 第二种:to的对象写法 -->
<router-link active-class="active" :to="{path:'/home'}">Home</router-link>

其实对象写法也分为两种,在学完命名之后可以有name和path两种写法 

6.命名路由 

 作用:可以简化路由跳转及传参

写法:name:'xxx'

这样写的话就可以在跳转路由的时候这样写:

7.嵌套路由 

假如想在新闻的展示区再做一个导航区和显示区,如图所示,这时候就需要嵌套路由。 

(1) 首先我们编写`News`的子路由,在pages下新建Detail.vue

<template><ul class="news-list"><li>编号:xxx</li><li>标题:xxx</li><li>内容:xxx</li></ul>
</template><script setup lang="ts" name="About"></script><style scoped>
.news-list {list-style: none;padding-left: 20px;
}.news-list>li {line-height: 30px;
}
</style>

(2)配置路由规则,使用children配置项

用法:children:[{ path:'xxxx', componnent:xxxx}] 

{name: 'xinwen',path: '/news',component: News,children:[{path: 'detail',//嵌套路由路径不用加/component: Detail,}]},

(3) news.vue中跳转路由(记得要加完整路径)

<template><!-- 导航区 --><div class="news"><ul><li v-for="news in newsList" :key="news.id"><RouterLink to="/news/detail">{{ news.title }}</RouterLink></li></ul><!-- 展示区 --><div class="news-content"><RouterView></RouterView></div></div>
</template><script setup lang="ts" name="News">
import { reactive } from 'vue';
import { RouterView,RouterLink } from 'vue-router';const newsList = reactive([{id:'cgp01',title:'今天周一',content:'嘻嘻'},{id:'cgp02',title:'今天周二',content:'不嘻嘻'},{id:'cgp03',title:'今天周三',content:'不不嘻嘻细'},{id:'cgp04',title:'今天周四',content:'不不不嘻嘻'}
])
</script>

8.query参数 

我们发现上方实现的效果newscontent的数据是写死的,那怎么把数据传过去呢?

(1)传递参数 

用to传参有两种写法:

   // News.vue  <ul><li v-for="news in newsList" :key="news.id"><!-- 第一种写法 模板字符串写法 冗杂 --><!-- <RouterLink :to="`/news/detail?id=${news.id}`">{{ news.title }}</RouterLink> --><!-- 第二种写法 对象写法 --><RouterLink :to="{// path:'/news/detail',name:'xiangqing',query:{id:news.id,title:news.title,content:news.content}}">{{ news.title }}</RouterLink></li></ul>

(2) 接收参数

<template><ul class="news-list"><li>编号:{{query.id }}</li><li>标题:{{query.title}}</li><li>内容:{{query.content}}</li></ul>
</template><script setup lang="ts" name="About">
import { toRefs } from 'vue';
import { useRoute } from 'vue-router';
let route = useRoute()
// console.log(route);可以发现route上有我们需要的query参数
//解构让query参数等于route上面就不用写route.query.id
let { query } = toRefs(route) 
// 直接解构query一定丢失响应式,导致点两次导航区就不更新了
// 加上torefs是不让query丢失响应式
</script>

 需要注意的是 直接解构query一定会让其丢失响应式,导致点两次导航区就不更新了加上torefs是不让query丢失响应式。

9.params参数

第一种字符串:

<!-- params第一种 占位符+模板字符串 -->
<RouterLink :to="`/news/detail/${news.id}/${news.title}/${news.content}`">{{ news.title }}</RouterLink>

记得一定要占位符 

这里有个注意点,就是万一不想传content怎么办?就是在占位符后面加个?就好了 

 

第二种对象:

需要注意的是不能用path 

<!-- 第二种 对象 params --><RouterLink :to="{name: 'xiangqing', //用name跳转params: {id: news.id,title: news.title,content: news.title}}">{{ news.title }}</RouterLink>

备注1:传递`params`参数时,若使用`to`的对象写法,必须使用`name`配置项,不能用`path`。

备注2:传递`params`参数时,需要提前在规则中占位。

Detail.vue 

 10.路由的props配置

之前上面写的detail.vue很冗杂,我们可以利用props配置

(1)props布尔值写法 

 props的布尔值写法,作用:把收到了每一组params参数,作为props传给Detail组件(只能和params配合)

props:true

(2) props的函数写法(常用)

 作用:把返回的对象中每一组key-value作为props传给Detail组件

(3) 对象写法(少写)

作用:把对象中的每一组key-value作为props传给Detail组件

11.replace属性

1. 作用:控制路由跳转时操作浏览器历史记录的模式。

2. 浏览器的历史记录有两种写入方式:分别为push和replace:

push是追加历史记录(默认值)。

 replace是替换当前记录。

3. 开启`replace`模式:

<RouterLink replace .......>News</RouterLink>

添加replace之后不能前进后退 

 

12.编程式导航

先来实现一个效果,点击首页看三秒之后自动跳转到新闻页面。其实这就是实现了一个简单的编程式路由导航效果。

//home.vue
<script setup lang="ts" name="Home">
import { onMounted } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
onMounted(() => {setTimeout(() => {router.push('/news')}, 3000)
})
</script>

那么接下来做一个复杂一点的: 

 在新闻页面的导航区增加按钮,通过点击按钮实现跳转。其实这也是现实开发中常用的编程时路由导航,而且一般都比routerlink使用的多。而且在vue2中用这个点击次数多可能会报错,但是在vue3中并不会。

//news.vue
<template><div class="news"><!-- 导航区 --><ul><li v-for="news in newsList" :key="news.id"><!-- 通过点击按钮实现路由跳转 --><button @click="showNewsDetail(news)">查看新闻</button><RouterLink :to="{name: 'xiang',query: {id: news.id,title: news.title,content: news.content}}">{{ news.title }}</RouterLink></li></ul><!-- 展示区 --><div class="news-content"><RouterView></RouterView></div></div>
</template><script setup lang="ts" name="News">
import { reactive } from 'vue'
import { RouterView, RouterLink, useRouter } from 'vue-router'const newsList = reactive([{ id: 'asfdtrfay01', title: '很好的抗癌食物', content: '西蓝花' },{ id: 'asfdtrfay02', title: '如何一夜暴富', content: '学IT' },{ id: 'asfdtrfay03', title: '震惊,万万没想到', content: '明天是周一' },{ id: 'asfdtrfay04', title: '好消息!好消息!', content: '快过年了' }
])const router = useRouter()
//写一个接口限制类型防止news报错
interface NewsInter {id: string,title: string,content: string
}function showNewsDetail(news: NewsInter) {router.replace({name: 'xiang',query: {id: news.id,title: news.title,content: news.content}})
}

效果:

 

13.重定向

1. 作用:将特定的路径,重新定向到已有路由。

2. 具体编码: 

 

这样默认显示的教师你redirect后的页面。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/818085.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt---控件的基本属性

文章目录 enabled(控件可用状态)geometry(位置和尺寸)简单恶搞程序 windowIcon(顶层 widget 窗口图标)使用 qrc 机制 windowOpacity(窗口的不透明值)cursor(当鼠标悬停空间上的形状)自定义鼠标图标 toolTip(鼠标悬停时的提示)focusPolicy(控件获取焦点的策略)styleSheet(通过CS…

【Python实践应用】使用Python加载栅格数据

下面的代码实现的是加载伊宁市NDVI数据&#xff0c;首先进行相关的python包的导入&#xff0c;然后定义和读取我们需要加载的数据&#xff0c;这里我们使用的NDVI数据是将伊宁23年的NDVI数据合并成为了一张栅格图像&#xff0c;每个波段表示一年的 NDVI&#xff0c;我们这里显示…

MySQL学习笔记3——条件查询和聚合函数

条件查询和聚合函数 一、条件查询语句二、聚合函数1、SUM&#xff08;&#xff09;2、AVG()、MAX()、MIN()3、COUNT&#xff08;&#xff09; 一、条件查询语句 WHERE 和 HAVING 的区别&#xff1a; WHERE是直接对表中的字段进行限定&#xff0c;来筛选结果&#xff1b;HAVIN…

最新版IntelliJ IDEA 2024.1安装和配置教程 详细图文解说版安装教程

IntelliJ IDEA 2024.1 最新版如何快速入门体验?IntelliJ IDEA 2024.1 安装和配置教程 图文解说版 文章目录 IntelliJ IDEA 2024.1 最新版如何快速入门体验?IntelliJ IDEA 2024.1 安装和配置教程 图文解说版前言 第一步&#xff1a; IntelliJ IDEA 2024.1安装教程第 0 步&…

Java快速入门系列-7(测试与调试)

第七章:测试与调试 第7章:测试与调试7.1 单元测试(JUnit)7.1.1 为什么要进行单元测试7.1.2 JUnit基础7.1.3 断言7.1.4 测试套件7.2 集成测试与系统测试7.2.1 集成测试7.2.2 系统测试7.3 调试技巧与工具7.3.1 断点7.3.2 单步执行7.3.3 变量检查7.3.4 条件断点7.3.5 日志记录…

Playwright已经是目前最好的测试自动化工具了吗?

作者观点&#xff1a;很长时间以来&#xff0c;Selenium是QA工程师寻求测试自动化解决方案的首选测试框架。它能够测试任何浏览器&#xff08;这在IE浏览器的统治时期尤其重要&#xff09;和任何平台。然而&#xff0c;现在看来&#xff0c;那个时代已经过去了。 今天&#xf…

【嵌入式】SD NAND:小身躯蕴含大能量的新型嵌入式存储解决方案

&#x1f9d1; 作者简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向的学习指导…

如何在Linux通过docker搭建Plik文件系统并实现无公网IP管理内网文件

文章目录 1. Docker部署Plik2. 本地访问Plik3. Linux安装Cpolar4. 配置Plik公网地址5. 远程访问Plik6. 固定Plik公网地址7. 固定地址访问Plik 本文介绍如何使用Linux docker方式快速安装Plik并且结合Cpolar内网穿透工具实现远程访问&#xff0c;实现随时随地在任意设备上传或者…

JNI用法

提示&#xff1a;文章 文章目录 前言一、背景二、 2.1 2.2 总结 前言 前期疑问&#xff1a; 本文目标&#xff1a; 一 背景 之前搞过jni&#xff0c;之前是强哥指导搞的&#xff0c;现在感觉又忘了。 今天照着帖子再搞一次。参考帖子&#xff1a;https://blog.csdn.net/y…

前端 接口返回来的照片太大 加载慢如何解决

现象 解决 1. 添加图片懒加载 背景图懒加载 对背景图懒加载做的解释 和图片懒加载不同&#xff0c;背景图懒加载需要使用 v-lazy:background-image&#xff0c;值设置为背景图片的地址&#xff0c;需要注意的是必须声明容器高度。 <div v-for"img in imageList&quo…

交叉熵损失函数介绍

交叉熵是信息论中的一个重要概念&#xff0c;它的大小表示两个概率分布之间的差异&#xff0c;可以通过最小化交叉熵来得到目标概率分布的近似分布。 为了理解交叉熵&#xff0c;首先要了解下面这几个概念。 自信息 信息论的基本想法是&#xff0c;一个不太可能的事件发生了…

openwrt局域网配置多个IP

在局域网配置过程中&#xff0c;若是DHCP服务器关闭&#xff0c;又忘记了配置的ip&#xff0c;将很难访问到路由器重新进行配置。这种情况可以在路由器出厂时做一个备用ip去避免。 1.配置 以下是备用ip的配置方法&#xff0c;以SKYLAB的SKW99 WIFI模组为例进行说明&#xff1…

如何在树莓派安装Nginx并实现固定公网域名访问本地静态站点

文章目录 1. Nginx安装2. 安装cpolar3.配置域名访问Nginx4. 固定域名访问5. 配置静态站点 安装 Nginx&#xff08;发音为“engine-x”&#xff09;可以将您的树莓派变成一个强大的 Web 服务器&#xff0c;可以用于托管网站或 Web 应用程序。相比其他 Web 服务器&#xff0c;Ngi…

LeetCode 59.螺旋矩阵II

LeetCode 59.螺旋矩阵II 1、题目 力扣题目链接&#xff1a;59. 螺旋矩阵 II - 力扣&#xff08;LeetCode&#xff09; 给你一个正整数 n &#xff0c;生成一个包含 1 到 n2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 示例 1&#xff1…

你想来微软苏黎世混合现实研究中心学习和实习吗?

Microsoft Mixed Reality & AI Lab - Zurich 苏黎世混合现实研发中心简介 微软苏黎世混合现实与人工智能实验室概况 专注于利用计算机视觉绘制和理解环境&#xff0c;识别和跟踪相关物体&#xff0c;并帮助用户执行任务&#xff0c;构建混合现实的未来。该实验室还在探索混…

API接口淘宝开放平台item_get-获得淘宝商品详情API接口根据商品ID查询商品标题价格描述等详情数据

要使用淘宝开放平台的item_get API接口根据商品ID查询商品标题、价格、描述等详情数据&#xff0c;你需要先注册一个KEY账号&#xff0c;然后获取到api_key和api_secret。接下来&#xff0c;你可以使用Python的requests库来调用API接口。 以下是一个示例代码&#xff1a; # c…

网络管理实验二、SNMP服务与常用的网管命令

1 常用的网管命令 1.1 网络状态监视命令 包括以下命令&#xff1a;Ipconfig、ping、nslookup、dig、host ipconfig 作用&#xff1a;用来显示本机所有网卡的基本信息&#xff08;IP、掩码、网关、工作状态&#xff09;&#xff1b;用法&#xff1a;ipconfig展示&#xff1a;…

ExtendSim花生酱加工厂模型

该模型展示了ExtendSim可靠性模块与ExtendeSim离散速率技术相结合的协同作用。 在花生酱加工厂的最初阶段&#xff0c;花生经过烘烤和冷却。冷却后的花生经过热烫或水烫去外皮。这些经过漂白的花生进入过程的混合部分&#xff0c;在研磨机中用盐、葡萄糖和氢化油稳定剂将其粉碎…

如何通过Linux pciehp sysfs接口控制PCIe Slot电源状态?-3

pciehp sysfs接口电源控制与NVME驱动卸载的区别 从NVMe SSD设计本身而言&#xff0c;当通过pciehp sysfs接口对PCIe插槽执行Power Off操作时&#xff0c;由于NVMe SSD作为PCIe设备&#xff0c;其电源供应是直接依赖于所连接的PCIe插槽提供的。当插槽电源被关闭时&#xff0c;会…