Vue3:Vue Router的学习(四)
Vue Router的学习
官网:https://router.vuejs.org/zh/
安装和设置路由
安装:npm install vue-router@4
新建一个项目npm create vite@latest
,清空项目,在src下创建文件夹views,然后再创建两个vue文件(一个首页一个内容页);
然后在src目录下创建router目录,新建index.js文件
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
const routes = [
{
path: "/",
component: () => import("../views/index.vue")
},
{
path: "/content",
component: () => import("../views/content.vue")
}
]
// 创建路由器
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
两种路由模式的区别:
-
外观表现
- createWebHistory:URL 类似传统网址,如
https://example.com/path
,简洁美观。 - createWebHashHistory:URL 含
#
,如https://example.com/#/path
。
- createWebHistory:URL 类似传统网址,如
-
工作原理
- createWebHistory:用 HTML5 History API 改变历史记录,不刷新页面。
- createWebHashHistory:监听
hashchange
事件,hash 变化时更新组件。
-
服务器配置
- createWebHistory:需服务器特殊配置,否则刷新可能 404。
- createWebHashHistory:无需特殊配置,hash 变化不发请求。
-
兼容性
- createWebHistory:依赖 HTML5 API,旧浏览器可能不支持。
- createWebHashHistory:兼容性好,多数浏览器支持。
-
搜索引擎优化(SEO)
- createWebHistory:利于 SEO,爬虫易索引。
- createWebHashHistory:不利于 SEO,爬虫通常不处理 hash。
接下来,在main.js中进行注册
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router'
// 将router实例注册到vue中
createApp(App).use(router).mount('#app')
最后,在App.vue中添加<router-view/>
配置路径别名@和VSCode路径提示
在vite.config.js中进行路径别名的配置:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
// https://vite.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: { // 配置路径别名
'@': path.resolve(__dirname, 'src')
}
}
})
路由可以改写为:
{
path: "/",
component: () => import("@/views/index.vue")
},
下面我们配置路径提示,首先,在整个项目目录下创建jsconfig.json
文件,写入如下代码:
// 输入@之后进行路径提示
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"] // 配置 @ 符合指向 src目录及其子目录
}
}
}
使用查询字符串或路径传递参数
字符串传参:/content?id==100&title=张
路径传参:/user/007/name/张
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
const routes = [
{
path: "/",
component: () => import("@/views/index.vue")
},
{
path: "/content",
component: () => import("@/views/content.vue")
},
{
// 路径传参
// 必须保证访问的路径和对应的路由规则是一致的。
// 比如只访问/user/001就访问不到
// path: "/user/:id/name/:name",
// 加一个问号就可以访问
path: "/user/:id?/name/:name?",
component: () => import("@/views/user.vue")
}
]
// 创建路由器
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
router-link、定义别名、定义路由名称、编程式导航
定义别名,使用alias
{
path: "/",
// 定义别名
// alias: '/home',
// 定义多个别名:
alias: ['/home', '/index'],
component: () => import("@/views/index.vue")
},
router-link的使用:
<script setup>
</script>
<template>
首页 - zz.com <br>
<router-link to="/content?id=100&title=张">查询字符串传参</router-link><br>
<router-link to="/user/007/name/张">路径传参</router-link><br>
<!-- router-link的动态属性绑定 -->
<router-link :to="{path: '/content', query: {id: 200, title: 'vue'}}">查询字符串传参 - 动态属性绑定</router-link> <br>
<!-- 路径传参:使用路径名称,传参使用params -->
<router-link :to="{name: 'member', params: {id: 111, name: 'zz'}}">路口传参 - 动态属性绑定</router-link><br>
</template>
<style scoped>
</style>
router-link和 a标签的区别:
-
功能用途
- router - link:是 Vue Router 提供的组件,专门用于实现单页面应用(SPA)内的路由跳转,在不刷新整个页面的情况下切换视图。
- a 标签:是 HTML 原生标签,用于在网页中创建超链接,可实现页面内跳转、跳转到外部网站或下载文件等,通常会导致页面刷新。
-
渲染结果
- router - link:最终会渲染成
a
标签,可通过tag
属性指定渲染成其他标签。 - a 标签:本身就是 HTML 标签,直接渲染为超链接。
- router - link:最终会渲染成
-
路由处理
- router - link:会自动处理路由逻辑,能通过
to
属性指定路由路径,支持命名路由、带参数路由等多种形式,还可配合 Vue Router 的导航守卫进行路由控制。 - a 标签:仅将
href
属性中的 URL 发送给浏览器,浏览器根据该 URL 发起请求,没有内置的路由处理机制。
- router - link:会自动处理路由逻辑,能通过
-
样式与激活状态
- router - link:可自动添加激活状态类名(如
router - link - active
),方便进行样式设置,以区分当前激活的路由链接。 - a 标签:需手动编写 JavaScript 代码或使用 CSS 伪类(如
:active
、:visited
)来处理样式变化。
- router - link:可自动添加激活状态类名(如
接下来,编程式导航。
import { useRouter } from 'vue-router';
const router = useRouter()
const goTo = () => {
// router.push("/content?id=07&title=张zz")
// 跳转到用户页
router.push({name: 'member', params: {id: 111, name: 'zz'}})
}
嵌套路由结合共享组件
添加如下文件:
在路由文件中加入如下代码
{
path: "/vip",
component: () => import("@/views/vip.vue"),
children: [
{
path: "",
component: () => import("@/views/vip/default.vue")
},
{
path: "order",
component: () => import("@/views/vip/order.vue")
},
{
path: "info",
component: () => import("@/views/vip/info.vue")
}
]
},
rooter-view:根据不同的子路由加载不同的子页面
组件:共享的组件,不需要路由嵌套
重定向
{
path: '/svip',
// 重定向:访问svip直接跳到了/vip页面
// redirect: "/vip"
// 重定向到用户页面,并携带参数
redirect:{name: 'member', params: {id: 111, name: 'zz'}}
}
全局前置守卫
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
// 将router实例注册到vue中
// createApp(App).use(router).mount('#app')
const app = createApp(App)
app.use(router)
// 全局前置守卫
router.beforeEach((to, from, next) => {
console.log("to:", to) // 即将进入的路由信息
console.log("from:", from) // 当前即将离开的路由信息
// 继续执行
// next()
if (to.name == "member") {
next(false) // 拦截
} else {
next() // 继续
}
})
app.mount("#app")