首页 > 其他分享 >Vue笔记7--路由管理Vue-router

Vue笔记7--路由管理Vue-router

时间:2022-12-16 10:33:57浏览次数:66  
标签:vue -- Vue path 组件 router id 路由

Vue-router

路由核心:改变URL,但是页面不进行整体刷新。路由理解为指向的意思,其中有很重要的一个关键就是路由表。

路由表,是一个映射表,一个路由就是一组映射关系,key:value key用来表示路由,value可以是function或者是Component(组件)。

后端路由value为function用来处理客户端的请求,前端路由value为Component用来展示内容。

vue-router是基于路由和组件的,路由是用来设定访问路径,将路径和组件映射起来

npm install vue-router@4





项目结构



JavaScript

在src下创建router文件夹,新建index.js

从官网的router->基础->入门->JavaScript下复制1-4点

// 1. 定义路由组件.
// 也可以从其他文件导入
const Home = { template: '<div>Home</div>' }
const About = { template: '<div>About</div>' }

// 2. 定义一些路由
// 每个路由都需要映射到一个组件。
// 我们后面再讨论嵌套路由。
const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About },
]

// 3. 创建路由实例并传递 `routes` 配置
// 你可以在这里输入更多的配置,但我们在这里
// 暂时保持简单
const router = VueRouter.createRouter({
  // 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。
  history: VueRouter.createWebHashHistory(),
  routes, // `routes: routes` 的缩写
})

但还不能进行能够使用要稍加更改

在src下创建views文件,存放路由组件,新建Home.vueAbout.vue分别写上

<template>
    <div>home</div>
</template>
<template>
    <div>about</div>
</template>

index.js修改步骤1

// 1.从其他文件导入
import Home from '../views/Home.vue'
import About from '../views/About.vue'

步骤2中如果导入名字不同,需要修改component: Home

步骤3和4中可以不使用VueRouter.来获得createRouter。先在index最开始引入

import {createRouter,createWebHashHistory} from 'vue-router'

然后去掉VueRouter.

const router = createRouter({
  history: createWebHashHistory(),
  routes, 
})

步骤4 有history模式也有hash模式,以后会讲解。

最后在结尾导出

export default router

在main.js中引入再使用

注意:这里是有先后顺序的app中用了路由,所以router要在前使用

//此处/index.js可省略会默认找到
import router from './router/index.js'

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



HTML

用自定义组件 router-link 代替a标签,最后渲染出来是a标签。达到可以在不重新加载页面的情况下更改 URL的目的,to填index.js步骤2中routes的path

<router-link to="/">Go to Home</router-link>

router-view

路由出口,占位符。路由匹配到的组件将渲染在这里

<router-view></router-view>





动态路由匹配



相应路由参数变化

比如在views下有一个User.vue组件,我希望不同的用户都能以这个组件为基础填上不同的信息。

App.vue

<router-link to="/use/123">Go to User</router-link>

此时我想要拿到数据123,需要

index.js

路径字段以冒号开始/user/:id,id的值将会在每个组件中以this.$router.params的形式暴露出params是参数的意思。但组合式API无法使用,因为setup中没有this。

注:动态路由无论id是什么都会进入user页面

const routes = [
    ...
    { path: '/user/:id', component: User },
]

Vue2做法

User.vue

<script>
export default{
    mounted(){
        console.log(this.$route.params.id)
    }
}
</script>

vue3做法

User.vue

vue-router引入useRoute()函数,再然后通过params访问id等参数。

<script setup>
import { useRoute } from 'vue-router';
    console.log(useRoute().params.id);
</script>



404页面

当输入不匹配的路由的时候我希望返回404页面

veiws文件夹下新建NotFound.vue。再在indes.js中引入,定义路由的时候使用正则的方式。

/:path(.*)表示匹配任意页面,但是如果前面出现了匹配成功的就不会走到正则这里。

const routes = [
    ...
    { path: '/:path(.*)', component: NotFound },
]



路由正则

?表示0个或1个 +号1个或多个 *号0个或多个

新建News.vue并且在index中导入

需求:动态路由的参数一定为数字。双杠表示匹配,d表示数字,+表示后面都为数字。[0-9]*也可。

const routes = [
    ...
    { path: "/news/:id(\\d+)", component:News}
]

需求:有多个参数也同样可以匹配,比如/news/123/aaa。+表示接受多个参数。

{
    path: "/news/:id+",
    component: News 
},

需求:参数可有可无,*和?表示参数可有可无。但是两者不同的点是问号不接受多个参数,比如/news/123/aaa

{ 
        //path: "/news/:id*",
        path: "/news/:id?",
        component: News 
},





嵌套路由

某些页面是多层组件嵌套的,子路由可以通过数据判断进哪一个。

在views中新建Parent.vue Styleone.vue Styleweo.vue

index.js

children:定义子路由,和routes一样以数组的形式定义,只是path前不需要加斜杠

const routes = [
    ...
    {
        path: '/parent',
        component: Parent,
        children: [
            { path: "styleone", component: StyleOne },
            { path: "styleone", component: StyleTwo },
        ]
    },
]

Parent.vue

<div>
    <h2>父组件Parent</h2>
    <RouterLink to="/parent/styleone">样式1</RouterLink>
    <RouterLink to="/parent/styletwo">样式2</RouterLink>
    <RouterView></RouterView>
</div>





JS转跳页面

除了RouterLink的转跳方法,比如登陆的时候我需要验证过后才允许转跳。

在 Vue 实例中,你可以通过 $router(一个对象) 访问路由实例。因而可以可以调用 this.$router.push、forword(返回)、go方法。

$route则是当前活跃的路由对象,在这里面就可以拿到path、params、query、name等。

在views中新建Page.vue

<button @click="goPage">跳转页面</button>
export default{
    methods:{
        goPage:function(){
            if (1 == 2)
                this.$router.push('/')
        }
    }
}



传入对象

this.$router.push({path:"/"})



带参数

this.$router.push({path:"/user/123456"})

或者利用name和params:分开写

index.js

const routes = [
    {name: "news",path: "/news/:id?",component: News},]

Page.vue

this.$router.push({ name: "news", params: { id: 123 } })



带问号

通过query:接受带问号的

this.$router.push({ path: "/about", query: { name: "zhangsan" } })

点击跳转网址显示为

http://localhost:5173/#/about?name=zhangsan

此时在About.vue中即可获取query里面内容,vue3中引入userRouter

export default{
    mounted(){
        console.log(this.$route.query.name)
    }
}





前进后退



替换当前位置

如果在一次访问ABC页面之后,B页面不想第二次展示,那么需要在历史纪录中,用C直接覆盖替换B。可在传递给 router.push中增加一个属性 replace: true

this.$router.push({ path: "/about", query: { name: "zhangsan" } ,replace:true})

或者用replace方法替换push

this.$router.replace({ path: "/about", query: { name: "zhangsan" } })



横跨历史

在历史堆栈中前进or后退多少步

About.vue

vue2写法

$router.go()方法参数正前进,负后退

 <button @click="goBack()">后退</button>
export default{
    methods:{
        goBack(){
            this.$router.go(-1)
        }
    }
}

vue3中引入userRouter后

router.go(-1)





命名路由

除了 path ,给路由起一个名字 name。下优点:

  • 没有硬编码的 URL
  • params 的自动编码/解码。
  • 防止你在 url 中出现打字错误。
  • 绕过路径排序(如显示一个)

App.vue

想要让to识别对象,绑定一下变成动态的

<router-link :to="{name:'news',params:{id:456}}">Go to News</router-link>

命名视图

在项目结构上components一般用于存放独立或者公共的组件,在views实际开发中通常会再根据页面新建文件夹,比如一个Home放着该页面下的组件

现在需求访问单个路径显示多个视图,同级展示。如访问/shop同时显示三个组件。(但似乎这种方式用的少)

新建ShopTop.vue ShopMain.vue ShopFooter.vue

index.js中引入

小名:组件。default:是必要的,提供默认显示。ShopTop:ShopTop可属缩写。

    {
        path:"/shop",
        components:{
            default:ShopMain,
            ShopTop,
            ShopFooter:ShopFooter,
        }
    },

App.vue

<router-view name="ShopTop"></router-view>
<router-view></router-view>
<router-view name="ShopFooter"></router-view>





重定向和别名



redirect:

当我希望访问//home链接都是home页面,可以在定义路由中使用redirect:

重定向

const routes = [
    {   path: '/',
        redirect:'/home'
    },
    { path: '/home', component: Home },
]

命名路由

除了路径还可已使用name

const routes = [
    {   path: '/',
        redirect: {name:"home"}
    },
    { path: '/home', name: "home", component: Home },
]

返回方法

这种做法可以在函数里写上判断,比如访问/:123参数to参会包含id=123的数据(但是不推荐),返回值可以是path也可以是name

const routes = [
    {   path: '/:id',
        redirect:(to)=>{
            console.log(to)
            return {path: '/home'}
        }
    },
]



alias:

起别名,数组形式可以

{path: '/parent',alias: '/father',...},
alias: ['/father', '/fuqin']





路由组件传参

使用$routeuseRoute()从URL上获得参数,会导致和路由紧密耦合,可以通过 props 配置来解除这种行为。


布尔模式

index.js

设置 props:true

const routes = [
    { 
        path: '/user/:id', 
        component: User,
        props:true,
    },
]

User.vue

vue2做法,此时this.id完美替代上面一句$route

<script>
export default {//路由组件传参vue2用法
    props: ['id'],
    mounted() {
        //console.log(this.$route.params.id);
        console.log(this.id);
    }
}
</script>

vue3做法,使用defineProps(),参数必为String类型

<script setup>
//import { useRoute } from 'vue-router';
//console.log(useRoute().params.id);
const props = defineProps({
    id: String
})
console.log(props.id)
</script>



命名视图

index.js

以数组的形式设置 props:

{
        path: "/shop/:id",
        components: {
            default: ShopMain,
            ShopTop,
            ShopFooter,
        },
        props:{default:true,ShopFooter:false,ShopTop:false}
    },

vue2做法,同布尔模式

vue3做法,同布尔模式

对象模式和函数模式具体见文档





历史记录模式



Hash模式

hash 模式是用 createWebHashHistory() 创建。标准是 URL 之前使用了一个哈希字符(#

http://localhost:8888/#/shop/123
const router = createRouter({
    history: createWebHashHistory(),
    routes, 
})
export default router



HTML5模式

createWebHistory() 创建 HTML5 模式,推荐使用这个模式,但是后端没配好就容易404

import {...,createWebHistory} from 'vue-router'
...
const router = createRouter({
    history:createWebHistory(),
    routes, 
})
export default router

即可访问

http://localhost:8888/home





导航守卫

通过跳转或取消的方式守卫导航。方式:全局的,单个路由独享的,或者组件级的。



全局前置守卫

用的较多,又称全全局守卫

使用 router.beforeEach 注册一个全局前置守卫,进入每一个路由组件的时候都会触发填入的回调函数。

回调函数参数1to去哪里,参数2from从哪来。

index.js

router.beforeEach((to, from) => {
    console.log(to)
    console.log(from)
})

参数3next导航守卫,当添加这个参数的时候,只有成功next()才会跳转。

router.beforeEach((to, from, next) => {
    console.log(to)
    console.log(from)
    next()//通行证
})



局部路由守卫

又称每路守卫,作用于单个路由,使用beforEnter:参数还是to、form、next

index.js

    {
        path: '/about',
        component: About,
        //每路守卫,独享的守卫
        beforeEnter: (to, from, next) => {
            console.log(to)
            console.log(from)
            if (1 == 1) {
                next()
            }
        }
    },



组件内的守卫

类似生命周期钩子,可以为路由组件添加以下配置:

  • beforeRouteEnter
  • beforeRouteUpdate
  • beforeRouteLeave

News.vue

<script>
export default {
    beforeRouteEnter() {
        console.log('路由进入组件之前');
    },
    beforeRouteUpdate() {
        console.log('路由更新组件之前');
    },
    beforeRouteLeave() {
        console.log('路由离开组件之前');
    },
}
</script>

同样也有参数to、form、next,因为beforeRouteEnter是还拿不到实例对象(另外两个可以),所以需要next写回调函数。

vm是自己取名的参数,相当于外面的this

export default {
    data() {
        return {
            age: 18,
        };
    },
    beforeRouteEnter(to, from, next) {
        next((vm)=>{
            console.log(vm.age)
        })
    },
}





路由懒加载

如果一次性要在index.js中引入非常多的组件,会导致加载很慢。

//静态导入
import Home from '../views/Home.vue'
...

路由懒加载,用到时候再加载

    {
        path: '/home',
        name: "home",
        component:()=>import('../views/Home.vue')
    },

但是更建议在抽取出来更好管理

const Home = () => import('../views/Home.vue')
const routes = [
    {
        path: '/home',
        name: "home",
        //component: Home
        component: Home
    },
]

标签:vue,--,Vue,path,组件,router,id,路由
From: https://www.cnblogs.com/TimothyWen/p/16986652.html

相关文章

  • 【卫朋】3000+ 字 | 2022年产品人必备的23个设计类网站(2.0版)
    卫朋丨第122篇原创文章阅读提示丨3061字5分钟常用资源,大家可先收藏资源在手,思路我有设计资源网站是产品人打基础的一个有效手段,是解答设计命题的思路参考。但资源诚可贵,实......
  • Java并发多线程高频面试题
    并发知识不管在学习、面试还是工作过程中都非常非常重要,看完本文,相信绝对能助你一臂之力。1、线程和进程有什么区别?线程是进程的子集,一个进程可以有很多线程。每个进程都有......
  • 认证管理(锐捷网关篇)
    大家好,我是小杜,明天又是周末了,按照师傅的“专政”──不允许周末来公司,可以去下现场看下,只能“勉为其难”在家好好休息了,呵呵呵......轻轻拍了下自己嘴巴来回神,......
  • 强化学习 学习资料汇总强化学习:Q-learning与DQN(Deep Q Network)
    python机器学习四(强化学习)DQN算法流程​​https://www.jianshu.com/p/42507aa63b05/https://www.jianshu.com/p/42507aa63b05/​​基于深度强化学习的智能体系结构参数调......
  • 微信小程序ucharts、echarts层级太高,遮挡底部tabbar,或者遮挡自定义头部区域
    一般在开发者工具中正常显示,而在真机上则会遮挡,ucharts,echarts基于层级比tab高,调过两者的z-index是不生效的使用cover-view和cover-image标签 代替原来view和image标签......
  • 计算机中的数学【集合论】现代数学的共同基础
    数学如何一步步从初级向高级发展,更高级别的数学对于具体应用究竟有何好处?集合论:现代数学的共同基础现代数学有数不清的分支,但是,它们都有一个共同的基础——集合论——因为......
  • 系统架构设计师考试
    今天,查了分数。结果出乎意料。考后自我感觉这次肯定考不过。自我预测,上午基础知识可以考50分,案例题40分,论文30分。预测结果就是无法通过。真实结果,基础知识40分,案例54分......
  • 怎样评价国产报表工具和BI软件
    如果说有什么通用软件领域是国内产品的技术要比国外产品更好,那估计只有报表工具了。数据库、操作系统这些耳熟能详的基础软件,国产货和外国货相比是个什么状态,大家也都心知肚......
  • 图书推荐:Kotlin从入门到进阶实战
    图片发自简书App《Kotlin从入门到进阶实战》从Kotlin语言的基础语法讲起,逐步深入到Kotlin进阶实战,并在最后配合项目实战案例,重点介绍了使用Kotlin+SpringBoot......
  • 【云原生 | Kubernetes篇】自建高可用k8s集群搭建
    文末有惊喜文章目录​​自建高可用k8s集群搭建​​​​一、所有节点基础环境​​​​1、环境准备与内核升级​​​​2、安装Docker​​​​二、PKI​​​​三、证书工具准备......