2024-02-19
Vue
0
请注意,本文编写于 493 天前,最后修改于 423 天前,其中某些信息可能已经过时。

目录

路由
单页面应用
路由器工作模式
history 模式
hash 模式
一级路由
嵌套路由
路由传递参数
query 参数
params 参数
路由的 props 配置
replace 属性
编程式路由导航
重定向

路由

  • 路由就是一组 key - value 的对应关系
  • 多个路由 route 需要经过路由器 router 的管理
  • 路由组件一般存放在 pagesviews,一般组件一般存放在 components
  • 路由组件会进行挂载和卸载
  1. 后端路由:

    • 理解: valuefunction, 用来处理客户端提交的请求
    • 注册路由: router.get(path, function(req, res))
    • 工作过程:当node接收到一个请求时, 根据请求路径找到匹配的路由, 调用路由中的函数来处理请求, 返回响应数据
  2. 前端路由:

    • 浏览器端路由,valuecomponent,用于展示页面内容
    • 注册路由: <Route path="/test" component={Test}>
    • 工作过程:当浏览器的path变为/test时, 当前路由组件就会变为Test组件

单页面应用

  1. 单页Web应用(single page web application,SPA)。
  2. 整个应用只有一个完整的页面
  3. 点击页面中的链接不会刷新页面,只会做页面的局部更新。
  4. 数据都需要通过ajax请求获取, 并在前端异步展现。

路由器工作模式

history 模式

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

缺点:后期项目上线需要服务端配合处理路径问题,否则容易 404

Vue2:mode: 'history'

Vue3:history: createWebHistory()

React:<BrowserRouter></BrowserRouter>

hash 模式

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

缺点:在SEO优化方面相对较差

一级路由

@/router/index.ts

typescript
// 创建一个路由器并暴露出去 import { createRouter, createWebHistory } from 'vue-router'; import Home from '@/views/Home.vue'; import News from '@/views/News.vue'; import About from '@/views/About.vue'; const router = createRouter({ history: createWebHistory(), // 路由器工作模式 routes: [ // 路由规则 { path: '/home', component: Home }, { name: 'xinwen', path: '/news', component: News }, { path: '/about', component: About } ] }); export default router;

@/App.vue

vue
<template> <div class="app"> <h2 class="title">Vue 路由</h2> <!-- 导航区 --> <div class="nav"> <RouterLink to="/home" active-class="active">首页</RouterLink> <RouterLink :to="{name: 'xinwen'}" active-class="active">新闻</RouterLink> <RouterLink :to="{path: '/about'}" active-class="active">关于</RouterLink> </div> <!-- 展示区 --> <div class="content"> <RouterView /> </div> </div> </template> <script setup lang="ts"> import { RouterView, RouterLink } from 'vue-router'; </script>

嵌套路由

为每一个路由配置 children 属性,子级路由不需要写 /<RouterLink>to 属性指向的 path 要写完整

typescript
const router = createRouter({ history: createWebHistory(), // 路由器工作模式 routes: [ // 路由规则 { path: '/home', component: Home }, { name: 'xinwen', path: '/news', component: News, children: [ { path: 'detail', // 子级路由不需要写 / component: Detail } ] }, { path: '/about', component: About } ] });
vue
<RouterLink to="/news/detail">{{ news.title }}</RouterLink> <div class="content"> <RouterView></RouterView> </div>

路由传递参数

query 参数

传递参数

vue
<ul> <li v-for="news in newsList" :key="news.id"> <!-- 写法一 --> <!-- <RouterLink :to="`/news/detail?id=${news.id}&title=${news.title}&content=${news.content}`">{{ news.title }}</RouterLink> --> <!-- 写法二 --> <RouterLink :to="{ path: '/news/detail', query: { id: news.id, title: news.title, content: news.content } }"> {{ news.title }} </RouterLink> </li> </ul>

接收参数

vue
<template> <ul class="news-list"> <li>编号:{{ query.id }}</li> <li>标题:{{ query.title }}</li> <li>内容:{{ query.content }}</li> </ul> </template> <script setup lang="ts"> import { toRefs } from 'vue'; import { useRoute } from 'vue-router'; let route = useRoute(); let { query } = toRefs(route); </script>

params 参数

  • params 参数需要在定义路由时进行描述,如:path: 'detail/:id/:title/:content?'
  • 非必需参数用 ? 表示
  • <RouterLink>to 采用对象写法时,要使用 name 而不是 path

传递参数

vue
<!-- 写法一 --> <!-- <RouterLink :to="`/news/detail/${news.id}/${news.title}/${news.content}`">{{ news.title }}</RouterLink> --> <!-- 写法二 --> <RouterLink :to="{ name: 'xiangqing', params: { id: news.id, title: news.title, content: news.content } }">

接收参数

vue
<template> <ul class="news-list"> <li>编号:{{ route.params.id }}</li> <li>标题:{{ route.params.title }}</li> <li>内容:{{ route.params.content }}</li> </ul> </template> <script setup lang="ts"> import { toRefs } from 'vue'; import { useRoute } from 'vue-router'; let route = useRoute(); // let { query } = toRefs(route); </script>

路由的 props 配置

在路由规则中配置

typescript
{ path: 'detail/:id/:title/:content?', // 子级路由不需要写 / name: 'xiangqing', component: Detail, // 写法一,将路由收到的所有 params 参数作为 props 传给路由组件 // props: true // 写法二,自己决定将什么作为 props 传给路由组件 /* props(route) { return route.query; // 可以传递 query 参数 } */ // 写法三,对象写法,数据是写死的 props: { a: 100, b: 200, c: 300 } }

接收时,直接在路由组件中使用 defineProps() 进行调用即可

vue
<template> <ul class="news-list"> <li>编号:{{ id }}</li> <li>标题:{{ title }}</li> <li>内容:{{ content }}</li> </ul> </template> <script setup lang="ts"> defineProps(['id', 'title', 'content']) </script>

优雅!

replace 属性

路由的跳转默认是 push 模式,可以通过在 <RouterLink> 上添加 replace 属性切换为 replace 模式

编程式路由导航

使用 useRouter() 得到路由器,可进行 push 和 replace 操作

vue
<template> <div class="news"> <!-- news 导航区 --> <ul> <li v-for="news in newsList" :key="news.id"> <button @click="showNewsDetail(news)">查看新闻</button> <RouterLink :to="{ name: 'xiangqing', params: { id: news.id, title: news.title, content: news.content } }"> {{ news.title }} </RouterLink> </li> </ul> <!-- news 展示区 --> <div class="content"> <RouterView></RouterView> </div> </div> </template> <script setup lang="ts"> import { reactive } from 'vue'; import { useRouter } from 'vue-router'; const newsList = reactive([ { id: 'abc01', title: '新闻001', content: '这是新闻001的内容abc' }, { id: 'abc02', title: '新闻002', content: '这是新闻002的内容def' }, { id: 'abc03', title: '新闻003', content: '这是新闻003的内容ghi' }, { id: 'abc04', title: '新闻004', content: '这是新闻004的内容jkl' } ]); const router = useRouter(); const showNewsDetail = (news: {id: string, title: string, content: string}) => { router.push({ name: 'xiangqing', params: { id: news.id, title: news.title, content: news.content } }) } </script>

重定向

typescript
{ path: '/', redirect: '/home' }

redirect 也可以接收一个函数,动态返回重定向目标

typescript
{ // /search/screens -> /search?q=screens path: '/search/:searchText', redirect: to => { // 方法接收目标路由作为参数 // return 重定向的字符串路径/路径对象 return { path: '/search', query: { q: to.params.searchText } } }, }

本文作者:Morales

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 License 许可协议。转载请注明出处!