前言

用 Vue.js + vue-router 创建单页应用,是非常简单的。使用 Vue.js ,我们已经可以通过组合组件来组成应用程序,当你要把 vue-router 添加进来,我们需要做的是,将组件(components)映射到路由(routes),然后告诉 vue-router 在哪里渲染它们。

Vue Router包含的功能有(来源于官网):

  • 1、嵌套的路由/视图表

  • 2、模块化的、基于组件的路由配置

  • 3、路由参数、查询、通配符

  • 4、基于 Vue.js 过渡系统的视图过渡效果

  • 5、细粒度的导航控制

  • 6、带有自动激活的 CSS class 的链接

  • 7、HTML5 历史模式或 hash 模式,在 IE9 中自动降级

  • 8、自定义的滚动条行为

hash 和 history模式

hash模式:以#/开始匹配,这种叫作哈希模式(hash),这是开发中的默认模式。

特点:

  • 1、在浏览器方面其支持度极佳,甚至兼容低版本的ie浏览器。

  • 2、window是可以监听到哈希值的变化的(onhashchage事件),这就意味着:当url中的哈希值发生了变化,无需发起http请求,window也可以监听到这种变化,并按需加载前端的代码块。

  • 3、路由分发不需要服务器来做,前端自己就可以完成。

  • 4、使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。

window.onhashchange = function(event){
  console.log(event.oldURL, event.newURL);
  let hash = location.hash.slice(1);
  document.body.style.color = hash;
}

上面的代码可以通过改变hash来改变页面字体颜色,虽然没什么用,但是一定程度上说明了原理。

HTML5 History 模式:以/开始,就是我们常见的方式没有 # 符号,是传统的路由分发模式。这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。

示例:

const router = new VueRouter({
  mode: 'history',
  routes: [...]
})

当你使用 history 模式时,URL 就像正常的 url,例如 http://yoursite.com/user/id,也好看!

<router-view/>

每次切换路由的时候,里面的内容都依靠<router-view/> 来显示在页面上。只有页面有导航的地方,打算让组件显示在页面上,必须写<router-view/>这个标签。

<router-view> 组件是一个 functional 组件,渲染路径匹配到的视图组件。<router-view> 渲染的组件还可以内嵌自己的 <router-view>,根据嵌套路径,渲染嵌套组件。

HTML代码

<template>
  <div id="app">
     <!-- 使用 router-link 组件来导航. --> 
      <!-- 通过传入 `to` 属性指定链接. --> 
      <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
    <router-link to="/foo">home主页</router-link>
    <router-link to="/bar">我的工作</router-link>
    <!-- 路由出口 --> <!-- 路由匹配到的组件将渲染在这里 -->
    <router-view/> 这个标签用来显示页面内容
  </div>
</template>

JavaScript代码

// 0. 如果使用模块化机制编程,导入 Vue 和 VueRouter,要调用 Vue.use(VueRouter) 
// 1. 定义(路由)组件。
// 可以从其他文件 import 进来
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
 
// 2. 定义路由
// 每个路由应该映射一个组件。 其中"component" 可以是
// 通过 Vue.extend() 创建的组件构造器,
// 或者,只是一个组件配置对象。
// 我们晚点再讨论嵌套路由。
const routes = [
  { path: '/foo', component: Foo },
  { path: '/bar', component: Bar }
]
 
// 3. 创建 router 实例,然后传 `routes` 配置
// 你还可以传别的配置参数, 不过先这么简单着吧。
const router = new VueRouter({
  routes // (缩写)相当于 routes: routes
})
 
// 4. 创建和挂载根实例。
// 记得要通过 router 配置参数注入路由,
// 从而让整个应用都有路由功能
const app = new Vue({
  router
}).$mount('#app')
 
// 现在,应用已经启动了!

<router-link> 相关属性

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

to

表示目标路由的链接。当被点击后,内部会立刻把 to 的值传到 router.push(),所以这个值可以是一个字符串或者是描述目标位置的对象。

<!-- 字符串 -->
<router-link to="home">Home</router-link>
<!-- 渲染结果 -->
<a href="home">Home</a>
 
<!-- 使用 v-bind 的 JS 表达式 -->
<router-link v-bind:to="'home'">Home</router-link>
 
<!-- 不写 v-bind 也可以,就像绑定别的属性一样 -->
<router-link :to="'home'">Home</router-link>
 
<!-- 同上 -->
<router-link :to="{ path: 'home' }">Home</router-link>
 
<!-- 命名的路由 -->
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
 
<!-- 带查询参数,下面的结果为 /register?plan=private -->
<router-link :to="{ path: 'register', query: { plan: 'private' }}">Register</router-link>

replace

设置 replace 属性的话,当点击时,会调用 router.replace() 而不是 router.push(),于是导航后不会留下 history 记录。

<router-link :to="{ path: '/abc'}" replace></router-link>

append

设置 append 属性后,则在当前 (相对) 路径前添加基路径。例如,我们从 /a 导航到一个相对路径 b,如果没有配置 append,则路径为 /b,如果配了,则为 /a/b

<router-link :to="{ path: 'relative/path'}" append></router-link>

tag

有时候想要 <router-link> 渲染成某种标签,例如 <li>。 于是我们使用 tag prop 类指定何种标签,同样它还是会监听点击,触发导航。

<router-link to="/foo" tag="li">foo</router-link>
<!-- 渲染结果 -->
<li>foo</li>

active-class

设置链接激活时使用的 CSS 类名。默认值可以通过路由的构造选项 linkActiveClass 来全局配置。

<style>
   ._active{
      background-color : red;
   }
</style>
<p>
   <router-link v-bind:to = "{ path: '/route1'}" active-class = "_active">Router Link 1</router-link>
   <router-link v-bind:to = "{ path: '/route2'}" tag = "span">Router Link 2</router-link>
</p>

exact

“是否激活”默认类名的依据是包含匹配。 举个例子,如果当前的路径是 /a 开头的,那么 <router-link to="/a"> 也会被设置 CSS 类名。

按照这个规则,每个路由都会激活 <router-link to="/">!想要链接使用“精确匹配模式”,则使用 exact 属性:

<!-- 这个链接只会在地址为 / 的时候被激活 -->
<router-link to="/" exact></router-link>

event

声明可以用来触发导航的事件。可以是一个字符串或是一个包含字符串的数组。

<router-link v-bind:to = "{ path: '/route1'}" event = "mouseover">Router Link 1</router-link>

以上代码设置了 event 为 mouseover ,及在鼠标移动到 Router Link 1 上时导航的 HTML 内容会发生改变。

exact-active-class

配置当链接被精确匹配的时候应该激活的 class。注意默认值也是可以通过路由构造函数选项 linkExactActiveClass 进行全局配置的。

<p>
   <router-link v-bind:to = "{ path: '/route1'}" exact-active-class = "_active">Router Link 1</router-link>
   <router-link v-bind:to = "{ path: '/route2'}" tag = "span">Router Link 2</router-link>
</p>

项目中的路由实例

首先在项目中,在router文件夹下创建index.js的路由文件

123.png

代码示例:

import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router);
const routes = [
  {
    path:'/',
    name:'Index',
    component:resolve => require(['../views/front/index'],resolve)
  },
  {
    path:'/detail/:id',
    name:'Detail',
    component:resolve => require(['../views/front/detail'],resolve)
  }
];
const router = new Router({
  mode:'history',
  linkExactActiveClass: 'myClass', //全局配置 <router-link> 默认的精确激活的 class
  routes
});
export default router;

然后在main.js中引入:

import Vue from 'vue'
import App from './App'
import router from './router/index'
import VueRouter from 'vue-router'
Vue.use(VueRouter);
Vue.config.productionTip = false
new Vue({
  el: '#app',
  router:router,
  template: '<App/>',
  components: { App }
})

路由嵌套 chidren

{
	path: '/about',  // 这是一级路由
	component: About,
	children: [{  // 里面是嵌套路由
			path: 'blog',  //如果在这个嵌套
			name: 'blog',
			component: Blog
		},
		{
			path: '/info',// 以 / 开头的嵌套路径会被当作跟路径
			name: 'info',
			component: Info
		}
	]
}

如果在这个嵌套里面的path:'' 留空,默认会显示这个组件

http://localhost:8080/#/about
此时会把 这个默认留空的嵌套路由组件显示出来,也就是上面的blog 组件显示出来

如果嵌套路由里面的path:'blog' 写具体的路由,则访问的时候必须匹配

必须是这个路由精准匹配
http://localhost:8080/#/about/blog
这样才会把这个blog嵌套路由组件显示出来

上段代码中,children嵌套路由中,以 / 开头的嵌套路径会被当作跟路径,如 /info,访问方式会变成:

http://localhost:8080/#/info

如果去掉/ 此时去掉了 '/blog' -> 'blog',则访问方式:

http://localhost:8080/#/about/blog

重定向

通过 to.path 可以获取当前用户访问的路径,来写一些逻辑跳转下面是使用详细方式

{
    path: '*',
    // component: NotFound,
    redirect: (to) => {
        console.log(to);
        if (to.path === '/aaa') {
            return '/work'
        } else if (to.path === '/bbb') {
            return '/info'
        } else {
            return '/'
        }
    }
}

路由传参

传一个参数

在路由里面的 path:'/detail/:id'   这个冒号后面跟的字符串相当于 key 
在组件里面使用 this.$route.params.id 来获取这个value的值
访问方式:
http://localhost:8080/#/detail/123
123 就是console.log(this.$route.params.id) 值

传多个参数

在路由里面添加多个key
path: '/detail/:id?/:name?
访问方式
http://localhost:8080/#/detail/123/dupeng
打印结果 console.log(this.$route.params)
{id: "123", name: "dupeng"}
{
  path:'/detail/:id?/:name?',
  name:'Detail',
  component:resolve => require(['../views/front/detail'],resolve)
}

参考资料

本文一些概念性的总结基本是拿来主义,并结合项目实践及个人理解,以此文为志。

https://router.vuejs.org/zh/

https://segmentfault.com/a/1190000011612365

https://www.runoob.com/vue2/vue-routing.html

作者: 一蓑烟雨

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

分类: Vue.js
posted 阅读(9 ) 评论(0 )

评论内容: