vue3路由基础

路由安装和简单使用

安装路由组件 npm i vue-router

scr/pages下创建三个基础组件(路由组件:通过路由渲染的组件)

Home.vue News.vue About.vue

vue 复制代码
<template>
    <div>this is about</div>
</template>

创建文件 src/router/index.ts,创建路由规则

typescript 复制代码
import {createRouter, createWebHistory} from 'vue-router'
import Home from '@/pages/Home.vue'

// 创建路由规则
const router = createRouter({
    history: createWebHistory(),
    routes: [{
        path: '/home',
        component: Home
     },{
        path: '/news',
        component: () => import('@/pages/News.vue')
     },{
        path: '/about',
        component: () => import('@/pages/About.vue')
     },
    ]
})

// 导出路由规则
export default router;

main.js引入路由规则

js 复制代码
import { createApp } from 'vue'
import App from './App.vue'
import router from 'vue-router'

const app = createApp(App)
app.mount('#app')
app.use(router)

App.vue 使用路由组件

vue 复制代码
<template>
  <div class="app">
    <h2>vue路由示例</h2>
    <!-- 导航区 -->
    <div class="nav">
      <router-link to="/home">首页</router-link>
      <router-link to="/news">新闻</router-link>
      <router-link :to="{path: '/about'}">关于</router-link>
    </div>
    <!-- 展示区 -->
     <div class="content">
      <router-view></router-view>
     </div>
  </div>
</template>

以上是基本用法示例,注意点:1,路由组件通常放大pages或views文件夹下,一般组件放components文件夹下。2,通过点击导航切换路由页面,消失的页面会被卸载,使用时会重新挂载

路由器工作模式

history模式(推荐)

优点:URL中不带#,更加美观 缺点:项目上线时服务端需要配置路径问题(try_files),否则刷新会有404问题

hash模式

优点:兼容性更好,不需要处理路径问题 缺点:URL 中带#,SEO优化也不好

命名路由

创建路由规则是新增name配置

typescript 复制代码
// 创建路由规则
const router = createRouter({
    history: createWebHistory(),
    routes: [{
        path: '/home',
        name: 'jia',
        component: Home
     }
    ]
})

使用时可以用对象写法的to

vue 复制代码
<router-link :to="{name:'jia'}">首页</router-link>

嵌套路由

修改news.vue内容如下

vue 复制代码
<template>
   <div>
    <!-- 导航区 -->
     <ul><li v-for="n in news" :key="n.id">
        <!-- to里面要从第一级开始,并且别忘了开头要有/ -->
        <router-link to="/news/detail">{{n.title}}</router-link>
    </li></ul>

    <!-- 展示区 -->
    <router-view></router-view>
   </div>
</template>
<script setup lang="ts">
import { reactive } from 'vue';

 const news = reactive([
    {id: 1, title: 'news1', content: 'news1 content'},
    {id: 2, title: 'news2', content: 'news2 content'},
    {id: 3, title: 'news3', content: 'news3 content'},
    {id: 4, title: 'news4', content: 'news4 content'},
    {id: 5, title: 'news5', content: 'news5 content'}
 ])
</script>

<style scoped>
div {
    display: flex;
}
</style>

创建子路由页面pages/Detail.vue

vue 复制代码
<template>
    <ul>
        <li>编号:xxx</li>
        <li>标题:xxx</li>
        <li>内容:xxx</li>
    </ul>
</template>

修改news的路由规则如下:

typescript 复制代码
{
  path: '/news',
  name: 'news',
  component: () => import('@/pages/News.vue'),
  children: [{
      path: 'detail',
      component: () => import('@/pages/Detail.vue')
  }]
}

以上是嵌套路由基本内容,detail页面都是写死的,如果需要不同新闻展示不同内容,就需要学习如何传参

query参数

最简示例

vue 复制代码
// News.vue 修改如下:使用query传参a、b
<router-link to="/news/detail?a=1&b=2">{{n.title}}</router-link>

// Detail.vue修改如下,引入useRoute,从route中的query种读取传过来的值
<template>
    <ul>
        <li>编号:{{route.query.a}}</li>
        <li>标题:{{route.query.b}}</li>
        <li>内容:xxx</li>
    </ul>
</template>

<script setup>
import {useRoute} from 'vue-router'
const route = useRoute()
</script>

模板字符串方式

vue 复制代码
// News.vue 修改如下:使用query传参,模板字符串方式
<router-link :to="`/news/detail?id=${n.id}&title=${n.title}&content=${n.content}`">{{n.title}}</router-link>
// Detail.vue修改如下
<ul>
    <li>编号:{{route.query.id}}</li>
    <li>标题:{{route.query.title}}</li>
    <li>内容:{{ route.query.content }}</li>
</ul>

// 优化Detail.vue 
<template>
    <ul>
        <li>编号:{{query.id}}</li>
        <li>标题:{{query.title}}</li>
        <li>内容:{{ query.content }}</li>
    </ul>
</template>

<script setup>
import { toRefs } from 'vue';
import {useRoute} from 'vue-router'
const route = useRoute()
const {query} = toRefs(route)
</script>
// 误区:query方式传不了对象类型,如下:
<router-link :to="`/news/detail?new=${n}`">{{n.title}}</router-link>

优化,to的对象类型传参

vue 复制代码
// 优化News.vue,使用对象to传参方式
<ul><li v-for="n in news" :key="n.id">
    <router-link :to="{
        path: '/news/detail',
        query: {
            id: n.id,
            title: n.title,
            content: n.content
        }
    }">{{n.title}}</router-link>
</li></ul>

// 也可以使用命名路由方式,修改router/index.ts下的路由规则,detail命名为d
{
  path: '/news',
  name: 'news',
  component: () => import('@/pages/News.vue'),
  children: [{
      name: 'd',
      path: 'detail',
      component: () => import('@/pages/Detail.vue')
  }]
}

// 优化News.vue,使用对象to传参方式,通过命名路由跳转
<router-link :to="{
    name: 'd',
    query: {
        id: n.id,
        title: n.title,
        content: n.content
    }
}">{{n.title}}</router-link>

params参数

首先修改路由规则:必须是命名路由,path里面定义入参:xxx,后面跟?代表可选参数

typescript 复制代码
{
  path: '/news',
  name: 'news',
  component: () => import('@/pages/News.vue'),
  children: [{
      name: 'd',
      path: 'detail/:id/:title/:content?',
      component: () => import('@/pages/Detail.vue')
  }]
}

News.vue改为如下params传参

vue 复制代码
<router-link :to="{
    name: 'd',
    params: {
        id: n.id,
        title: n.title,
    }
}">{{n.title}}</router-link>

Detail.vue使用

vue 复制代码
<template>
    <ul>
        <li>编号:{{params.id}}</li>
        <li>标题:{{params.title}}</li>
        <li>内容:{{ params.content }}</li>
    </ul>
</template>

<script setup>
import { toRefs } from 'vue';
import {useRoute} from 'vue-router'
const route = useRoute()
const {params} = toRefs(route)
</script>

路由的props参数

给新闻的路由规则添加props:true配置,将路由收到的所有params参数作为props传给路由组件

typescript 复制代码
children: [{
    name: 'd',
    path: 'detail/:id/:title/:content?',
    component: () => import('@/pages/Detail.vue'),
    props: true // 将路由收到的所有params参数作为props传给路由组件
}]

然后在Detail.vue中就可以直接使用defineProps接收使用了

vue 复制代码
<template>
    <ul>
        <li>编号:{{id}}</li>
        <li>标题:{{title}}</li>
        <li>内容:{{ content }}</li>
    </ul>
</template>

<script setup>
defineProps(['id', 'title', 'content'])
</script>

第二种写法,从query中读取

typescript 复制代码
children: [{
    name: 'd',
    path: 'detail',
    component: () => import('@/pages/Detail.vue'),
    props(route) { // 函数写法,可以自己决定将什么作为props给路由组件
        return route.query
    }
}]

// 注意News.vue需要改为query传参路由跳转
<router-link :to="{
    name: 'd',
    query: {
        id: n.id,
        title: n.title,
        content: n.content
    }
}">{{n.title}}</router-link>

第三种写法,对象写法,可以自己决定将什么作为props给路由组件(使用极少,不能动态内容)

typescript 复制代码
props: {
  id: 123,
  title: '新闻详情',
  content: '新闻内容'
}

replace属性

页面跳转默认是push模式,页面记录可以前进后退,router-link 添加replace属性即可实现替换当前记录,例如:

vue 复制代码
<router-link replace :to="{name:'jia'}">首页</router-link>

编程式路由导航

不通过点击router-link进行路由页面跳转,比如我们打开页面3s之后自动跳转到新闻页面

在App.vue页面加载时执行3s延迟执行事件,使用router.push跳转,入参和to一样,可以是字符串也可以是对象

vue 复制代码
<script setup lang="ts">
import { onMounted } from 'vue';
import { useRouter } from 'vue-router';

const router = useRouter();
onMounted(() => {
  setTimeout(() => {
    router.push({
      name: 'news'
    });
  }, 3000);
});
</script>

新闻列表项都加一个按钮,点击按钮去看新闻详情

vue 复制代码
<ul><li v-for="n in news" :key="n.id">
  <button @click="showNewsDetail(n)">点我看详情</button>
  <router-link :to="{
      name: 'd',
      query: {
          id: n.id,
          title: n.title,
          content: n.content
      }
  }">{{n.title}}</router-link>
</li></ul>

<script setup lang="ts">
import { reactive } from 'vue';
import { useRouter } from 'vue-router';

const router = useRouter();
function showNewsDetail(n) {
    router.push({
        name: 'd',
        query: n
    })
}
...
</script>

使用params实现同样的功能

typescript 复制代码
// 路由规则修改path和props为params方式传参
children: [{
    name: 'd',
    path: 'detail/:id/:title/:content',
    component: () => import('@/pages/Detail.vue'),
    props(route) {
        return route.params
    }
}]

// News.vue 修改点击事件的时候params作为push参数
function showNewsDetail(n) {
    router.push({
        name: 'd',
        params: n
    })
}

路由重定向

给路由规则添加如下内容即可,指定重定向到那个首页路由

json 复制代码
{
  path: '/',
  redirect: '/home'
}
相关推荐
狂炫一碗大米饭1 小时前
如何优化vue中的渲染🔒🔑🔓
vue.js
歪歪1001 小时前
Vue原理与高级开发技巧详解
开发语言·前端·javascript·vue.js·前端框架·集成学习
用户6757049885023 小时前
一文吃透 Promise 与 async/await,异步编程也能如此简单!建议收藏!
前端·javascript·vue.js
summer7774 小时前
开箱即用的openlayer地图效果
前端·javascript·vue.js
三小河4 小时前
详解React.memo的更新机制
前端·javascript·vue.js
张志鹏PHP全栈4 小时前
Vue第十四天,Vue3路由(第一部分)
前端·vue.js
wycode4 小时前
Vue2源码笔记(2)编译时-模板代码是怎么生效的之从AST生成渲染代码
前端·vue.js
袋鱼不重4 小时前
手把手搭建Vue轮子从0到1:6. Computed 源码解读
前端·vue.js·面试
李长鸿4 小时前
vue3基础学习
vue.js