Vue Router 用法笔记

基础配置

// /src/router/index.js
import VueRouter from 'vue-router'
import Vue from 'vue'
import Home from '@/components/Home'
import About from "@/components/About"

// 1. 通过Vue.use(插件) 来安装这个插件
Vue.use(VueRouter)

// 写一些配置路径
const routes = [
{
path: '', //或'/'
redirect: '/home' //重定向, 直接跳转到/home下
},
{
path: '/about',
component: About
},
{
path: '/home',
component: Home
}
]

// 2. 创建一个路由对象
const router = new VueRouter({
// 配置路由和组件之间的应用关系
routes,
})


// 3. 将router对象传递给Vue实例
export default router
// main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router/index'

Vue.config.productionTip = false
new Vue({
render: h => h(App),
// router: router
router
}).$mount('#app')
<!-- App.vue -->
<template>
<router-link to="/home" tag="button" replace>首页</router-link>
<router-link to="/about" tag="button" replace>关于</router-link>
<router-view></router-view>
</template>

<script>
// ...
</script>
  • router-link会被默认渲染成a标签

history模式

默认情况下是hash模式, 要改成history模式, 需要在index.js里进行设置

hash模式:

url: localhost:8080/#/home

history模式:

url: localhost:8080/home

// /src/router/index.js
// 2. 创建一个路由对象
const router = new VueRouter({
// 配置路由和组件之间的应用关系
routes,
mode: 'history'
})

router-link的其他属性

<!--App.vue-->
<template>
<router-link to="/home" tag="button" replace>首页</router-link>
<router-link to="/about" tag="button" replace>关于</router-link>
<router-view></router-view>
</template>
  • to: 到哪儿

  • tag: 渲染成什么组件, 不用的话是<a>

  • replace: 如果使用了replace, 就不能用浏览器的前进和后退

  • active-class: 当<router-link>对应的路由匹配成功时, 会自动给当前元素设置一个router-link-active的class, 设置active-class可以修改默认的名称

    • 在进行高亮显示的导航菜单或者底部tabbar时,会使用到该类.

      .router-link-acitve{
      'color': 'red'
      }
    • 但是通常不会修改类的属性,会直接使用默认的router-link -active即可.

    修改方式:

    <router-link to="/home" active-class="active">首页</router-link>
    // /src/router/index.js
    // 2. 创建一个路由对象
    const router = new VueRouter({
    // 配置路由和组件之间的应用关系
    routes,
    mode: 'history',
    linkAcitveClass: 'active'
    })

通过事件实现路由跳转

<!--App.vue-->
<template>
<button @click="toHome">首页</button>
<button @click="toAbout">关于</button>
<router-view></router-view>
</template>

<script>
export default{
name: 'App',
methods:{
toHome(){
// 不要这样做: 跳过了Vue
// history.pushState();
this.$router.push('/home'); // <--------
// 或
this.$router.replace('/home');
},
toAbout(){
this.$router.push('/about');
}
}
}
</script>

动态路由

处理一些path不确定的情况, 如:

/user/16656
/user/65455

// /src/router/index.js
// 写一些配置路径
const routes = [
{
path: '', //或'/'
redirect: '/home' //重定向, 直接跳转到/home下
},
{
path: '/user/:userId',
component: User
}
]
<!--App.vue-->
<template>
<router-link to="/home" tag="button" replace>首页</router-link>
<router-link to="/about" tag="button" replace>关于</router-link>
<router-link :to="''/user'+userId" tag="button" replace>用户</router-link>
<h2></h2>
<router-view></router-view>
</template>

<script>
export default{
name: 'App',
data(){
return{
userId: '123',
}
}
}
</script>

获取一些url里的参数:

<!--User.vue-->
<template>
<h2>{{userId}}</h2>
</template>

<script>
export default{
name: 'User',
computed:{
userId(){
return this.$route.params.userId
}
}
}
</script>

路由懒加载

解决打包时单个js文件过大的问题

方式一: 结合Vue的异步组件和Webpack的代码分析. (能看懂就行)

const Home = resolve => { require. ensure([ '../components/Home.vue' ], () => { resolve( require('../components/Home.vue'))})};

方式二: AMD写法

const About = resolve => require(['../components/About.vue'], resolve);

方式三: 在ES6中,我们可以有更加简单的写法来组织Vue异步组件和Webpack的代码分割.(常用)

// /src/router/index.js
// 写一些配置路径
const routes = [
{
path: '', //或'/'
redirect: '/home' //重定向, 直接跳转到/home下
},
{
path: '/home',
component: ()=>import('../components/Home') // <--- 懒加载
}
]

嵌套路由

实现类似如下的功能:

/home/news

/home/message

步骤:

  1. 创建对应子组件, 在路由映射中配置对应子组件
  2. 在组件内部使用<router-view>标签
// /src/router/index.js
import VueRouter from 'vue-router'
import Vue from 'vue'
import Home from '@/components/Home'
import About from "@/components/About"
import News from '@/components/News'
import Message from "@/components/Message"

// 1. 通过Vue.use(插件) 来安装这个插件
Vue.use(VueRouter)

// 写一些配置路径
const routes = [
{
path: '', //或'/'
redirect: '/home' //重定向, 直接跳转到/home下
},
{
path: '/about',
component: About
},
{
path: '/home',
component: Home,
children: [
{
path: '',
redirect: News
},
{
path: 'news',
components: News
},
{
path: 'message',
components: Message
}
]
}
]

// 2. 创建一个路由对象
const router = new VueRouter({
// 配置路由和组件之间的应用关系
routes,
})


// 3. 将router对象传递给Vue实例
export default router
<!--Home.vue-->
<template>
<router-link to="/home/news">新闻</router-link>
<router-link to="/home/message"消息</router-link>
<router-view></router-view>
</template>

(注意路径为: /home/news, 而不是/news)

路由参数传递

参数传递主要有两种方式: params和query

  • params类型(之前提到过)

    • 配置路由格式: /router/:id
    • 传递的方式: 在path后跟上对应的值
    • 传递后形成的路径: /router/123
    • 获取: route.params.id
  • query类型:

    • 配置路由格式: /router(普通配置)
    • 传递方式: 在对象中使用query的key作为传递方式
    • 传递后形成的路径: /router?id=123
  • 获取: route.query.id

    <!--App.vue-->
    <!--也可以在方法中跳转-->
    <template>
    <router-link :to="{path: '/home', query:{name:'123', age:18}}" >首页</router-link>
    <router-view></router-view>
    </template>

全局导航守卫

  • 一种利用生命周期函数实现监视页面变化

    created(){
    // 界面创建时
    }
    mouted(){
    // 界面挂载时
    }
    updated(){
    // 界面更新时执行
    }
  • 全局守卫 – 监听路由跳转 – hook

    // /src/router/index.js

    // 写一些配置路径
    const routes = [
    {
    path: '', //或'/'
    redirect: '/home' //重定向, 直接跳转到/home下
    },
    {
    path: '/about',
    component: About,
    meta: {
    title: '关于'
    }
    },
    {
    path: '/home',
    component: Home,
    meta: {
    title: '首页'
    }
    ]
    }
    ]

    // 2. 创建一个路由对象
    const router = new VueRouter({
    // 配置路由和组件之间的应用关系
    routes,
    })

    // 前置守卫(guard)
    router.beforeEach((to, from, next)=>{
    // 必须调一次next()
    document.title = to.meta.title;
    // document.title = to.matched[0].meta.title // 如果有路由嵌套
    next();
    })

    // 后置钩子(hook)
    router.afterEach((to, from)=>{

    })

next()用法很灵活

  • 这里只展示了全局守卫, 其实还有路由独享守卫和组件内的守卫

keep-alive

keep-alive是Vue内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。

router-view也是一个组件,如果直接被包在keep-alive里面,所有路径匹配到的视图组件都会被缓存:

<keep-alive>
<router-view/>
</keep-alive>
// 只有该组件被保持了keep-alive时, 才是有效的
activated(){
//,..
}
deactivated(){
//...
}

两个重要的属性

填写字符串或正则表达式, 只有匹配的组件才会/不会被缓存

<keep-alive include="About">
<router-view/>
</keep-alive>

<keep-alive exclude="About,User"> <!--这里不能随便加空格-->
<router-view/>
</keep-alive>