Vue系列入门教程(10)——vue-router路由之入门案例、命名路由和动态路由

Web前端 潘老师 2个月前 (09-05) 363 ℃ (1) 扫码查看

1、含义:
浏览器无论访问什么地址,访问的真实页面始终是index.htmlvue根据不同的地址,渲染不同的组件。由于真实页面是唯一的,用户看到的页面切换,实际上是组件的切换,这种应用称之为单页应用
Vue系列入门教程(10)——vue-router路由之入门案例、命名路由和动态路由
2、开发单页应用涉及到两个核心问题:

  • 在哪个位置切换组件
  • 访问路径如何对应组件

1、vue-router 是 Vue.js 官方的路由管理器,使用vue-router 可以非常轻松的构建单页应用程序。
官网地址:https://router.vuejs.org/zh/

2、路由实际上就是可以理解为指向,就是我在页面上点击一个按钮需要跳转到对应的页面,这就是路由跳转。

3、首先我们来学习三个单词:

  • route:首先它是个单数,译为路由,即我们可以理解为单个路由或者某一个路由;
  • routes:它是个复数,表示多个的集合才能为复数;即我们可以理解为多个路由的集合,JS中表示多种不同状态的集合的形式只有数组和对象两种,事实上官方定义routes是一个数组;所以我们记住了,routes表示多个数组的集合;
  • router:译为路由器,上面都是路由,这个是路由器,我们可以理解为一个容器包含上述两个或者说它是一个管理者,负责管理上述两个;举个常见的场景的例子:当用户在页面上点击按钮的时候,这个时候router就会去routes中去查找route,就是说路由器会去路由集合中找对应的路由;

4、路由模式:

  • hash:路径来自于地址栏中#后面的值,这种模式兼容性比较好,但是不好看,不符合用户习惯
  • history:路径来自于真实的地址路径,旧浏览器不兼容(我们这里使用这一种)
  • abstract:路径来自于内存(一般用于移动端)

1、、基于vue-cli创建名为router的vue项目

2、打开router项目终端,使用如下指令安装vue-router插件库

npm install vue-router

Vue系列入门教程(10)——vue-router路由之入门案例、命名路由和动态路由
3、在components下新建Header.vueFooter.vue公共组件
1)Header.vue代码-主要实现菜单

<template>
    <!-- 头部菜单 -->
    <div class="header">
        <!-- 使用 router-link 组件来导航. -->
        <!-- 通过传入 `to` 属性指定链接. -->
        <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
        <router-link to="/">首页</router-link>
        <router-link to="/blog">博客</router-link>
        <router-link to="/about">关于我们</router-link>
    </div>
</template>

<script>
    export default {
        
    }
</script>

<style scoped>
.header {
    width:1000px;
    margin:0 auto;
    height:80px;
    background:black;
    display:flex;
    justify-content: center;
    align-items:center;
}
.header a{
    font-size:18px;
    text-decoration: none;
    color:white;
    margin:0 10px;
}
</style>

2)Footer.vue代码

<template>
    <div class="footer">
        底部区域
    </div>
</template>

<script>
    export default {
        
    }
</script>

<style scoped>
.footer{
    width:1000px;
    line-height:80px;
    background: gray;
    margin:0 auto;
    text-align:center;
    color:white;
}
</style>

4、在src下新建views目录,主要放一些非公共页面组件
5、在views下新建Home.vueBlog.vueAbout.vue,分别代码主页、博客页和关于我们
1)Home.vue代码

<template>
    <div>
        这里是首页内容
    </div>
</template>

<script>
    export default {
        
    }
</script>

<style scoped>

</style>

2)Blog.vue代码

<template>
    <div>
        这里是博客内容
    </div>
</template>

<script>
    export default {
        
    }
</script>

<style scoped>

</style>

3)About.vue代码

<template>
    <div>
        这里是关于我们内容
    </div>
</template>

<script>
    export default {
        
    }
</script>

<style scoped>

</style>

6、在src下新建router目录,存放路由配置,并在router目录下新建config.jsindex.js
config.js代码如下:
1)写法1——不推荐

原因:因为如果页面太多,依赖就会越多,会导致加载一个页面时将依赖的也加载进来,所以我们需要使用延时加载,访问哪个路径就导入哪个页面

// 导入页面组件,@代表src目录,编译后代表根路径
import Home from '@/views/Home.vue'
import Blog from '@/views/Blog.vue'
import About from '@/views/About.vue'
// 导出路由配置
export default{
    // 1、路由模式
    mode:"history",
    // 2、路径配置,数组形式,一个路径对应一个对象
    routes:[
        {
            path:"/",
            component:Home
        },
        {
            path:"/blog",
            component:Blog
        },
        {
            path:"/about",
            component:About
        }
    ]
}

2)写法2——推荐-懒加载,用到哪个就加载哪个

// 导出路由配置
export default{
    // 1、路由模式
    mode:"history",
    // 2、路径配置,数组形式,一个路径对应一个对象
    routes:[
        {
            path:"/",
            component:()=>import('@/views/Home.vue')
        },
        {
            path:"/blog",
            component:()=>import('@/views/Blog.vue')
        },
        {
            path:"/about",
            component:()=>import('@/views/About.vue')
        }
    ]
}

index.js代码如下:

// 1、导入路由vue-router
import VueRouter from 'vue-router'
// 2、导入Vue
import Vue from 'vue'
// 3、导入路由配置
import config from './config.js'
// 4、Vue安装vue-router插件
Vue.use(VueRouter);
// 5、创建路由对象
const router = new VueRouter(config);
// 6、导出
export default router;

当然你也可以将这两个js合并到index.js文件中,如下:

// 1、导入vue-router
import VueRouter from 'vue-router'
// 2、导入vue
import Vue from 'vue'
// 3、安装
Vue.use(VueRouter)
// 4、创建VueRouter实例-路由对象
const router = new VueRouter({
    // 5、配置路由
    //5.1配置路模式
    mode:"history",
    // 5.2 配置路由对象数组
    routes: [
        {
            path:"/",
            component:()=>import('@/components/Home.vue')
        },
        {
            path:"/blog",
            component:()=>import('@/components/Blog.vue')
        },
        {
            path:"/about",
            component:()=>import('@/components/About.vue')
        }
    ]
})
// 6、导出路由对象
export default router;

7、在main.js中使用路由

import Vue from 'vue'
import App from './App.vue'
// 7、导入路由,/index.js可以省略会自动加载
import router from './router'
new Vue({
  render: h => h(App),
  // 8、通过 router 配置参数注入路由到vue实例中
  // 从而让整个应用都有路由功能
  router
}).$mount('#app')

通过注入路由器,我们可以在任何组件内通过 this.$router 访问路由器,也可以通过 this.$route 访问当前路由(后面演示)。

8、在App.vue中导入、注册、使用相关组件

<template>
  <div id="app">
    <!-- 头部 -->
    <Header/>
    <!-- 中间内容区域 -->
    <div class="container">
        <!-- 该组件会根据不同的访问路径,渲染不同的组件 -->
        <router-view></router-view>
    </div>    
    <!-- 底部 -->
    <Footer/>
  </div>
</template>

<script>
// 导入组件
import Header from './components/Header.vue'
import Footer from './components/Footer.vue'
export default {
  name: 'app',
  components: {
      // 注册组件
      Header,
      Footer
  }
}
</script>

<style>
.container{
    border: 1px solid gray; 
    margin:30px auto;
    width:1000px; 
    min-height: 200px;
} 
</style>

9、执行如下指令启动服务,运行至浏览器,访问

npm run serve

1)访问首页
Vue系列入门教程(10)——vue-router路由之入门案例、命名路由和动态路由
2)访问博客
Vue系列入门教程(10)——vue-router路由之入门案例、命名路由和动态路由
3)访问关于我们
Vue系列入门教程(10)——vue-router路由之入门案例、命名路由和动态路由

1、Header.vue中的template中,不使用a标签跳转原因:
因为如果使用a标签跳转,虽然能实现页面跳转,但点击上面的菜单访问,会发现了一个问题,就是页面会刷新,这会导致网站响应速度过慢,因为页面刷新的过程是这样的:

浏览器输入地址–>请求至服务器–>服务器返回html+css+js –>浏览器渲染页面,执行js –>创建vue实例–>渲染根组件->router-view标签根据不同的路径渲染不同的组件

最佳的方式就是直接通过router-view组件根据不同的路径渲染不同的组件,就是我们上面使用的router-link声明式导航组件。

2、router-link组件支持用户在具有路由功能的应用中点击导航。通过to属性指定目标地址,默认渲染为带有正确连接的a标签,可以通过配置tag属性生成别的标签。另外,当目标路由成功激活时,链接元素自动设置一个表示激活的css类名。
3、router-link组件的属性有(不作展开讲-了解):

  • to (必选参数):类型string/location,表示目标路由的链接,该值可以是一个字符串,也可以是动态绑定的描述目标位置的对象
  • replace类型: boolean,默认值: false,设置 replace 属性的话,当点击时,会调用 router.replace() 而不是 router.push(),于是导航后不会留下 history 记录
  • append类型: boolean,默认值: false,设置 append 属性后,则在当前 (相对) 路径前添加基路径
  • tag类型: string,默认值: “a”,指定router-link渲染成某种标签
  • active-class类型: string,默认值: “router-link-active”,设置 链接激活时使用的 CSS 类名。默认值可以通过路由的构造选项 linkActiveClass 来全局配置
  • exact 类型: boolean,默认值: false,”是否激活” 默认类名的依据是 inclusive match (全包含匹配)
  • event类型: string | Array<string>默认值: ‘click’,声明可以用来触发导航的事件,可以是一个字符串或字符串数组
  • exact-active-class类型: string,默认值: “router-link-exact-active”,配置当链接被精确匹配的时候应该激活的 class。注意默认值也是可以通过路由构造函数选项 linkExactActiveClass 进行全局配置的。

4、router-view组件:写在组件想要渲染的地方,等组件跳转过来就渲染,该组件会根据不同的访问路径,渲染不同的组件

以上Header.vue中的template中的router-linkto属性值,我们是写死的,效果不是太好,如果一旦菜单路由配置对应的跳转地址发生变化,则可能会需要做大量的修改,因此,我们可以做如下优化:
1)我们修改src\router目录下config.js,给每个路由配置使用name进行命名,让名称与路由地址对应:

// 导出路由配置
export default{
    // 1、路由模式
    mode:"history",
    // 2、路径配置,数组形式,一个路径对应一个对象
    routes:[
        {
            path:"/",
            name:"Home",
            component:()=>import('@/views/Home.vue')
        },
        {
            path:"/blog",
            name:"Blog",
            component:()=>import('@/views/Blog.vue')
        },
        {
            path:"/about",
            name:"About",
            component:()=>import('@/views/About.vue')
        }
    ]
}

2)修改Header.vue中的template,直接使用名称去路由配置中匹配路由地址,注意要使用:to,值为一个对象:

<template>
    <!-- 头部菜单 -->
    <div class="header">
        <router-link :to="{name:'Home'}">首页</router-link>
        <router-link :to="{name:'Blog'}">博客</router-link>
        <router-link :to="{name:'About'}">关于我们</router-link>
    </div>
</template>

3)测试效果与之前一样

1、捕获所有路由或404 Not Found路由

如果我们浏览器输入的一个地址,在我们的项目中并不存在对应的具体页面,即404找不到,这种不存在的地址有无限多种可能,这些请求路径,我们都交给一个404页面处理,那么对于404页面而言,就需要匹配所有不存在请求地址。
1)在components中新建NotFound.vue组件

<!-- 纯css 3D立体样式 -->
<template>
    <div class="container404">
        <div class="page404">
            <div class="f404"><span>4</span><span>0</span><span>4</span></div>
            <div class="f404-des">
                该页面不存在(´・ω・`)
            </div>
        </div>
    </div>
    
</template>

<script>
    export default {
        
    }
</script>

<style scoped>
.container404 {
  background-color: #ECECEC;
  font-family:Arial, Helvetica, sans-serif;
  font-size: 14px;
  color: #3c3c3c;
  padding:150px;
}
.page404 .f404{
  text-align: center;
  font-size: 150px;
  font-weight: bold;
  line-height: 100px;
  letter-spacing: 5px;
  color: #fff;
  margin-bottom:60px;
}

.page404 .f404 span {
  cursor: pointer;
  text-shadow: 0px 0px 2px #686868,
    0px 1px 1px #ddd,
    0px 2px 1px #d6d6d6,
    0px 3px 1px #ccc,
    0px 4px 1px #c5c5c5,
    0px 5px 1px #c1c1c1,
    0px 6px 1px #bbb,
    0px 7px 1px #777,
    0px 8px 3px rgba(100, 100, 100, 0.4),
    0px 9px 5px rgba(100, 100, 100, 0.1),
    0px 10px 7px rgba(100, 100, 100, 0.15),
    0px 11px 9px rgba(100, 100, 100, 0.2),
    0px 12px 11px rgba(100, 100, 100, 0.25),
    0px 13px 15px rgba(100, 100, 100, 0.3);
  -webkit-transition: all .1s linear;
  transition: all .1s linear;
}

.page404 .f404 span:hover {
  text-shadow: 0px 0px 2px #686868,
    0px 1px 1px #fff,
    0px 2px 1px #fff,
    0px 3px 1px #fff,
    0px 4px 1px #fff,
    0px 5px 1px #fff,
    0px 6px 1px #fff,
    0px 7px 1px #777,
    0px 8px 3px #fff,
    0px 9px 5px #fff,
    0px 10px 7px #fff,
    0px 11px 9px #fff,
    0px 12px 11px #fff,
    0px 13px 15px #fff;
  -webkit-transition: all .1s linear;
  transition: all .1s linear;
}

.page404 .f404-des{
  text-align: center;
  color: #666;
  font-family: cursive;
  font-size: 20px;
  text-shadow: 0 1px 0 #fff;
  letter-spacing: 1px;
  line-height: 2em;
}
</style>

2)在src\router目录下config.js,新增匹配所有请求的路由配置:

// * 号通配符,其他配置都未匹配到都会走这个配置,/user-*'会匹配以 `/user-` 开头的任意路径
{
    path:"*",
    name:"404",
    component:()=>import('@/components/NotFound.vue')
}

3)测试下效果:
Vue系列入门教程(10)——vue-router路由之入门案例、命名路由和动态路由


补充:
1、高级匹配模式:
vue-router 使用 path-to-regexp 作为路径匹配引擎,所以支持很多高级的匹配模式,例如:可选的动态路径参数、匹配零个或多个、一个或多个,甚至是自定义正则匹配。查看它的文档学习高阶的路径匹配,还有这个例子 展示 vue-router 怎么使用这类匹配
2、匹配优先级:
有时候,同一个路径可以匹配多个路由,此时,匹配的优先级就按照路由的定义顺序:谁先定义的,谁的优先级就最高。

2、响应路由参数的变化

1、我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个 User 组件,对于所有 username 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在 vue-router 的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果。
Vue系列入门教程(10)——vue-router路由之入门案例、命名路由和动态路由
2、在views目录下新建User.vue组件

<template>
    <div>
        欢迎 {{ $route.params.username }} 用户回来!
    </div>
</template>

<script>
    export default {
        
    }
</script>

<style scoped>

</style>

3、修改src\router目录下config.js,新增配置如下:

{ 
    path: '/user/:username', 
    name:'User',
    component:()=>import('@/views/User.vue')
}

现在呢,像 /user/foo/user/bar都将映射到相同的路由。一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到 this.$route.params,可以在每个组件内使用。

4、修改Header.Vuetemplate新增用户请求:

<!--params:传参  -->
<router-link :to="{name:'User',params:{username:'小明'}}">用户</router-link>
<!-- 或直接写地址然后动态拼接参数 -->
<!-- <router-link to="/user/小明">用户</router-link> -->

5、测试
Vue系列入门教程(10)——vue-router路由之入门案例、命名路由和动态路由
6、上面的理解了,类似/user/:username/post/:post_id多参数的应该也就会了
1)修改src\router目录下config.js,修改上面动态地址配置如下:

{ 
    path: '/user/:username/post/:post_id', 
    name:'User',
    component:()=>import('@/views/User.vue')
}

2)修改User.vuetemplate如下:

<template>
    <div>
        欢迎 {{ $route.params.username }} 用户回来,post_id: {{ $route.params.post_id }} 
    </div>
</template>

3)修改Header.Vuetemplate中动态地址:

<!--params:传参  -->
<router-link :to="{name:'User',params:{username:'小明',post_id:20}}">用户</router-link>
<!-- 或直接写地址然后动态拼接参数 -->
<!-- <router-link to="/user/小明/post/20">用户</router-link> -->

4)测试:
Vue系列入门教程(10)——vue-router路由之入门案例、命名路由和动态路由


版权声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系潘老师进行处理。
喜欢 (9)
请潘老师喝杯Coffee吧!】
分享 (0)
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填【保密】)
  • 网址
(1)个小伙伴在吐槽
  1. emmm
    Emmm2020-09-14 09:31 回复