Vue-router

# Vue-router

参考教程:从头开始学习vue-router (opens new window)

[TOC]

# 一、Vue-router

# 1.1 认识Vue-router

  • 这里的路由和平时使用的路由器没有关系,路由是根据不同的url地址展示不同的内容或页面。
  • Vue-router是链接路径管理系统。
  • 路由模块的本质就是在url和页面之间建立起建立关系。
  • 单页应用的核心:更新视图而不重新请求页面。

# 1.2 Vue-router入门代码

  • 新建工程
$ vue create my-router
$ npm install vue-router
1
2
  • main.js 入口文件
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')
1
2
3
4
5
6
7
8
9
10
11

# 二、实现方式

# 2.1 Hash 模式

vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。

  • hash(#)-URL锚点

    • 可用window.location.hash读取。

    • 代表的是网页中的一个位置,单单改变#后的部分,浏览器只会滚动到相应位置。

    • hash只出现在URL中,不会被包含在http请求中,故改变hash并不会重新加载页面。

    • 每次改变#后的内容,都会被浏览器记录,故可被回退按钮支持。

    • 即使后端没有做到路由全覆盖,也不会返回404错误。

# 2.2 History 模式

如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。

const router = new VueRouter({
  mode: 'history',
  routes: [...]
})
1
2
3
4
  • 利用HTML5新特性 - pushState()可以对浏览器历史记录栈进行修改。

    pushState会增加一条新的历史记录,而replaceState则会替换当前的历史记录,都会操作浏览器的历史记录,而不会引起页面的刷新。

    • 当它们执行修改时,虽然改变了当前的 URL ,但浏览器不会向后端发送请求。
  • 不足

    • 需要后端配置支持,如果配置错误会返回404的。
    • 对策:在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面。
    // 如果URL输入错误或者是URL 匹配不到任何静态资源,就自动跳到到Home页面 
    export const routes = [ 
      {path: "/", name: "homeLink", component:Home}
      {path: "/register", name: "registerLink", component: Register},
      {path: "/login", name: "loginLink", component: Login},
      {path: "*", redirect: "/"}]
    
    1
    2
    3
    4
    5
    6

    # 三、路由的使用

    具体看官方文档 (opens new window)就好,以下是补充部分和注意事项。

  • // to后面跟的链接应该是绝对路径
    <router-link to="/bar">Go to Bar</router-link>
    
    1
    2
  • 通过 this.$router 访问路由器,也可以通过 this.$route 访问当前路由。

  • 获取/cart?user=123问号后的参数是:$route.query.user

  • 命名路由要用v-bind:to="{ name:'user' }",相当于router.push({ name:'user' })

# 四、应用场景

# 4.1 Url改变但组件未变时,created 无法触发的问题

  • 这是因为 vue-router 会识别出这两个路由使用的是同一个组件,然后会进行复用,所以并不会重新创建组件,那么 created 周期函数自然也不会触发。

  • 解决方法:

    1. 监听 $route 的变化
    watch: {
        $route: {
            immediate: true,
            handler: '函数名'
        }
    }
    
    1
    2
    3
    4
    5
    6
    1. router-view添加key
    <router-view :key="$route.fullPath"></router-view>
    
    1

# 4.2 在新窗口打开页面

let routeData = this.$router.resolve({
    path: '/dataReport/index',
    query: {
    name,
    resume_key,
    handle: 'openResume'
    }
})
window.open(routeData.href, '_blank')
1
2
3
4
5
6
7
8
9

# 4.3 动态添加参数

const query = {...this.$route.query, pointCode: p.code} 
this.$router.replace({query})
1
2