目录
单页面应用程序
概念
整个应用只有一个入口网页文件(就是项目中index.html),换句话说,项目的所有功能都集中在同一个html中进行实现的,不会进行跳转。
举例
单页面应用程序:比如:网易云音乐、知乎等
多页面应用程序:比如:京东、淘宝、门户网站等
单页面应用 VS 多页面应用
开发分类 | 实现方式 | 页面性能 | 开发效率 | 用户体验 | 学习成本 | 首屏加载 | SEO |
---|---|---|---|---|---|---|---|
单页 | 一个html | 按需更新,高 | 高 | 好 | 高 | 慢 | 不利于 |
多页 | 多个html | 整页更新,低 | 低 | 差 | 低 | 快 | 利于 |
什么是SEO
SEO称为搜索引擎优化,可以通过优化网站的内容和解构,提高网站在搜索引擎中的排名,从而增加网站的流量和曝光度的一种技术。
路由
什么是路由
路由是一种映射关系,比如生活中的路由:设备与ip地址的映射关系
vue3中的路由
路径与组件的映射关系,也就是,访问不同的路径,要显示不同的组件页面。
在vue3中如何实现路由切换
借助vue-router第三方模块,也是vue3的官方路由管理器
在进行路由切换前,我们需要先了解一下vue文件的分类和他们存放目录的问题,方便后期管理。
vue文件的分类
- 页面组件:一个做好的,大的,成型的页面,比如京东的首页,只是用来做大块的展示,无需复用,配合路由切换
- 复用组件:一个个独立的小型也米娜,可复用的,用来组装页面的
存放目录
- 页面组件:存放在src/views目录下
- 复用组件:存放在src/components目录下
vue-router的基本使用
4个固定步骤
1、安装vue-router模块
npm i vue-router
如果出现类似下面的错误,可以更换成 pnpm i vue-router
npm error Cannot read properties of null (reading 'matches')
npm error A complete log of this run can be found in: C:\Users\L\AppData\Local\npm-cache\_logs\2024-12-03T02_31_00_941Z-debug-0.log
2、导入相关函数,在main.js中编写代码
import { createRouter, createWebHashHistory } from 'vue-router'
3、创建路由实例,还是在main.js中编写代码
//创建路由实例
const router=createRouter({
//指明路由模式,这里使用哈希模式,路径后面带#
history:createWebHashHistory(),
//路由表规则
routes:[]
})
4、注册路由实例
//注册路由实例
app.use(router)
路由表规则编写
语法:
routes:[
{
path:'自定义路径名',
component:导入的页面组件名
}
]
如下示例:
//导入页面组件
import Find from './views/Find.vue'
import My from './views/My.vue'
//创建路由实例
const router=createRouter({
//指明路由模式,这里使用哈希模式,路径后面带#
history:createWebHashHistory(),
//路由表规则
routes:[
{
path:'/find',
component:Find
},
{
path:'/my',
component:My
}
]
})
路由出口
编写完路由表规则后,需要在App.vue写入路由出口,路由出口就是路由表内,页面组件的显示位置
<router-view/>
抽离和封装路由模块
为什么要封装路由模块
如果把路由配置的代码都写在main.js中,会使main.js代码显得臃肿。为了便于后期对路由代码的管理和维护,最好的方式就是把路由相关的代码单独封装到一个模块中,这是一种模块化开发的思想
如何封装路由模块
1、新建/src/router/index.js,然后把之前写在main.js中的路由代码全部移植到router/index.js中进行管理,并导出router实例,示例代码如下:
//导入相关函数
import { createRouter, createWebHashHistory } from 'vue-router'
//导入页面组件
import Find from '@/views/Find.vue'
import My from '@/views/My.vue'
//创建路由实例
const router=createRouter({
//指明路由模式,这里使用哈希模式,路径后面带#
history:createWebHashHistory(),
//路由表规则
routes:[
{
path:'/find',
component:Find
},
{
path:'/my',
component:My
}
]
})
//导出路由实例
export default router
注意:
这里在导入两个页面组件时,路径使用@,在 vite.config.js有定义,表示src绝对路径
2、在main.js中导入router实例,并注册,示例代码如下:
import './assets/main.css'
import { createApp } from 'vue'
import App from './App.vue'
//导入路由实例
import router from './router/index.js'
const app=createApp(App)
//注册路由实例
app.use(router)
app.mount('#app')
声明式导航(重要)
声明式导航就是点击链接跳转页面
实现方法
<router-link to="/path值"> 我的 </router>
PS:router-link的本质就是a标签 ,to属性会变成href属性。因此需要给router-link添加style就是给a标签添加style。
使用router-link跳转后,当前激活的导航链接中的a标签默认加了两个类名
router-link-exact-active 和 router-link-active
我们可以通过给这两个类添加高亮样式实现选中导航的样式。如下:
<template>
<nav>
<router-link to="/my">我的</router-link>
<router-link to="/find">发现</router-link>
</nav>
<br/>
<router-view/>
</template>
<script setup>
import MyDialog from './components/MyDialog.vue';
</script>
<style scoped>
nav a{
color: #333;
text-decoration: none;
padding: 10px;
}
nav a.router-link-exact-active{
background-color: aqua;
color: blue;
}
</style>
router-link-exact-active 和 router-link-active区别
- router-link-active:模糊匹配,当浏览器 # 后面放入url地址包含to属性值的时候,则会给当前的a标签添加此类名
- router-link-active:精准匹配,当浏览器 # 后面放入url地址等于to属性值的时候,则会给a标签添加此类名
相等是一种特殊的包含关系,因此只要当浏览器 # 后面放入url地址等于to属性值的时候,两个类名都会添加
查询参传参
传递
适用于传递多个参数
1、传字符串
<router-link to="/path?参数名="值"&参数名="值""></router-link>
2、传对象
<router-link :to="{path:'/path值',query:{参数值:值,参数值:值}}"></router-link>
接收
import {useRoute} from 'vue-router'
//获取当前激活的路由对象
const route=useRoute()
const ret=route.query.参数名
动态路由传参
路径比较简短些,需要改写路由规则表的path值
传递
1、传字符串
<router-link to="/path/10086"></router-link>
因为这种方式传递,会改变#后面的url,因此,我们需要先改写路由表的path值
/friend/:fd //:fd占位,fd这个名字自定义
2、传对象
需要给路由表中路由表项添加一个name属性
routes:[
{
name:'Find',
path:'/find/:fd',
component:Find
},
{
name:'My',
path:'/my',
component:My
}
]
通过name、params传递
<router-link :to="{
name:"Find",
params:{
fd:123
}}"></router-link>
接收
import {useRoute} from 'vue-router'
//获取当前激活的路由对象
const route=useRoute()
const ret=route.params.参数名
路由的其他配置
重定向
默认打开页面,会访问/根路径,这里借助redirect,让其强制跳转到其他页面 ,如下:
routes:[
{
//配置这个路径,防止刚打开项目时,页面为空白
path:'/',
redirect:'/find'
},
{
path:'/find',
component:Find
},
{
path:'/my',
component:My
}
]
404页面
需求:如果路由能命中,则显示响应的页面;否则,显示一个404页面
方法:在路由表末尾,添加一个404规则,当前面路由都没有命中,才会执行这条路由
{path:'./pathMatch(.*)*',component:_404}
路由的模式
默认采用的是哈希模式,特点是路径上会带上一个#,如果不想要这个#,可以更改路由模式,改成history模式。
import { createWebHistory } from 'vue-router'
const router=createRouter({
//指明路由模式
history:createWebHistory (),
})
注意:在Vite开发环境下,我们可以正常使用历史模式进行切换路由;但是当项目打包上线的时候,要想用历史模式,需要服务器支持和配置.
编程式导航
前面的声明式导航是被动的跳转,在某些情况下,我们需要主动做路由跳转,比如:登录成功自动跳转至首页。
语法:
(1)获取router路由实例
import {useRouter} from 'vue-router'
const router=useRouter() //router是路由实例,也是createRouter()返回值
这里要与之前const route = useRoute()做一个区分,route是当前激活的路由对象,用来获取路由参数的
(2)router.push(字符串/对象)
<script setup>
import {useRouter} from 'vue-router'
import {onMounted} from 'vue'
const router = useRouter()
onMounted(()=>{
setTimeout(()=>{
//字符串的方式,传入path对应的字符串
router.push('/my')
//对象的方式,传入一个包含path属性的对象
router.push({path:'/my'})
//对象的方式,传入一个包含name属性的对象
router.push({name:'my'})
},2000)
})
</script>
编程式导航传参
编程式导航传参与声明式导航传参用法差不多
这里举例查询参传参
传字符串
router.push('/find?id=777')
传对象
router.push({
path:'/find',
query:{
id:777
}
路由嵌套
通过children添加子路由,编写规则与routes一致,包含path,component。子路由的path前面一般不添加 / ,记得编写完路由嵌套后,在需要添加子路由的页面组件中,添加路由出口和相应的router-link。
语法如下:
//路由表规则
routes:[
{
path:'/',
children:[
{
path:'reconmand',
component:reconmand
}
]
},
{
path:'/find',
component:Find
},
]
示例如下:
路由配置:
import {createRouter,createWebHashHistory} from 'vue-router'
import Home from '@/views/Home.vue'
import Message from '@/views/Message.vue'
import My from '@/views/My.vue'
import Show from '@/views/Show.vue'
const router=createRouter({
history:createWebHashHistory(),
routes:[
{
path:'/home',
component:Home,
children:[
{
path:'message',
component:Message
},
{
path:'show',
component:Show
}
]
},
{
path:'/message',
component:Message
},
{
path:'/my',
component:My
},
]
})
export default router
App.vue,最上层的导航
<template>
<nav>
<router-link to="/home">Home</router-link>
<router-link to="/my">About</router-link>
</nav>
<router-view></router-view>
</template>
<script setup>
</script>
<style scoped>
</style>
在Home页面添加子路由导航,也需要添加一个路由出口,代码如下:
<template>
<div>
<nav>
<router-link to="/home/message">Message</router-link>
<router-link to="/home/show">Show</router-link>
</nav>
<router-view></router-view>
</div>
</template>
<script setup>
</script>
<style scoped>
</style>
路由守卫
路由守卫,全称叫做路由全局前置守卫,在访问每个页面前,添加权限判断
语法:
router.beforeEach((to,from)=>{
//to:要去的路由对象
//from:当前的路由对象
//如果放行,返回true或undefined或者不写
//如果不放行,返回false
//重定向到某个指定路由,return 路径
})
示例:
const isLogin=false
//路由守卫
router.beforeEach((to,from,next)=>{
if(to.path=='/my'&&!isLogin){
alert('请先登录')
return false
}else{
return true
}
})