Vue-cli4——vue-router路由

Vue-cli4——vue-router路由(一)

Day1


文章目录

  • Vue-cli4——vue-router路由(一)
  • 前言
  • 一、代码解析
    • 1.1 src/router/index.js
    • 1.2 src/App.vue
  • 二、实例
    • 2.1 简单的实例
    • 2.2 在网页中不显示#号
    • 2.3 重定向
    • 2.4 router-link
    • 2.5 通过代码跳转
    • 2.6 路由懒加载
  • 三、嵌套与数据传递
    • 3.1 嵌套
    • 3.2 动态路由传递数据,params
    • 3.3 参数传递,query
    • 3.4 参数传递案例,params与query
    • 3.5 router与route的区别
    • 3.6 全局导航守卫
    • 3.7 keep-alive
  • 总结


前言

此文章根据官方文档及些网络资料编写,仅供个人使用。

提示:以下是本篇文章正文内容,下面案例可供参考

@vue/cli 4.5.8

一、代码解析

当你安装完以后,你会看到有着几个目录,route文件夹是放路由配置文件,而components是放组件,views是放页面。其他的不用管,用不到。
Vue-cli4——vue-router路由_第1张图片

1.1 src/router/index.js

第一步我们先来,分析src/router/index.js代码,我们先分段解释。

导入view文件夹里面的Home.vue为Home

import Home from '../views/Home.vue'

设置组件和路径映射关系
第 3 行:路径为 / 。
第 5 行:组件(component)为刚刚 import 进来的 Home 。

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: function () {
      return import(/* webpackChunkName: "about" */ '../views/About.vue')
    }
  }
]

将刚刚设置的 组件和路径映射 关系(routes)给到router

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
})

最后将router导出

export default router

1.2 src/App.vue

使用router-link标签,显示

<template>
  <div id="nav">
    <router-link to="/">Homerouter-link> |
    <router-link to="/about">Aboutrouter-link>
  div>
  <router-view/>
template>

二、实例

2.1 简单的实例

router-view 是决定模板渲染位置
App.vue

<template>
  <div id="nav">
    <router-link to="/test1">test1router-link> |
    <router-link to="/test2">test2router-link>
  div>
  <router-view/>
template>

components/test1.vue

<template>
  <div>
    <h2>我是测试1h2>
    <h2>我是测试1h2>
  div>
template>

components/test2.vue

<template>
  <div>
    <h2>我是测试2h2>
    <h2>我是测试2h2>
  div>
template>

couter/index.js

import test1 from '../components/test1'
import test2 from '../components/test2'

const routes = [
  {
    path: '/test1',
    name: 'test1',
    component: test1
  },
  {
    path: '/test2',
    name: 'test2',
    component: test2
  }
]

App.vue

<template>
  <div id="nav">
    <router-link to="/test1">test1router-link> |
    <router-link to="/test2">test2router-link>
  div>
  <router-view/>
template>

Vue-cli4——vue-router路由_第2张图片
当你点击test1的时候他下面会跟着变化。

2.2 在网页中不显示#号

因为在默认是用hash,我们现在就修改为history
src/router/index.js

// 在vue-cli3中
const router = createRouter({
  mode: 'history',
  routes
})
// 在vue-cli4中
const router = createRouter({
  history: createWebHistory(),
  routes
})

2.3 重定向

我们这里设置了当打开网页的时候,使用redirect重定向到 test1 页面里

  {
    path: '/',
    redirect: 'test1'
  }

2.4 router-link

使用的其他属性
tag,指定渲染成任意组件
replace,页面跳转的时候禁止返回
active-class,对应的路由匹配成功时, 会自动给当前元素设置一个router-link-active的class, 设置active-class可以修改默认的名称.


<template>
  <div id="app">
    <router-link to="/test1" tag="button" replace active-class="my-active">test1router-link> |
    <router-link to="/test2" tag="button" replace active-class="my-active">test2router-link>
  div>
  <router-view/>
template>
<style>
.my-active{
color: red;
}
style>
// router/index.js
  const router = createRouter({
  history: createWebHistory(),
  routes,
  linkActiveClass: 'my-active'
})

2.5 通过代码跳转

    <button @click="test1click">test1button>
    <button @click="test2click">test2button>
<script>
export default {
  name:'App',
  methods: {
    test1click() {
      this.$router.push('/test1')
      console.log('test1click')
    },
    test2click(){
      this.$router.push('/test2')
      console.log('test2click')
    }
  }
}
script>

2.6 路由懒加载

一个懒加载对应一个打包后的js文件

const home = () => import('../components/home')

三、嵌套与数据传递

3.1 嵌套

在children数组里写路由记录,其中redirect是设置重定向。

// router/index.js
const test1 = () => import('../components/home')
const routes = [
  {
    path: '/test1',
    name: 'test1',
    component: test1,
    children: [
      {
        path: '',
        redirect: '/test1/children1'
      },
      {
        path: 'children1',
        component: () => import('../components/children1')
      },
      {
        path: 'children2',
        component: () => import('../components/children2')
      }
    ]
  }
]

在 test1 里调用子组件


<template>
  <div>
    <h2>我是测试1h2>
    <h2>我是测试1h2>
    <router-link to="/test1/children1">children1router-link> |
    <router-link to="/test1/children2">children2router-link>
    <router-view>router-view>
  div>
template>

Vue-cli4——vue-router路由_第3张图片


3.2 动态路由传递数据,params

我们新建一个params.vue。
params.vue,中的abc是调用 router/index.js的abc。
params,是直接用浏览器地址后面的Id


<template>
  <div id="nav">
    <router-link to="/test1" tag="button">test1router-link> |
    <router-link to="/test2">test2router-link> |
    <router-link :to="'/params/' + paramsId">paramsrouter-link>
  div>
  <router-view/>
template>
<script>
export default {
  name: 'App',
  data() {
    return {
      paramsId: 'params'
    }
  }
}
script>


<template>
  <div>
    <h2>我是paramsh2>
    <h2>{{$route.params.abc}}h2>
  div>
template>
<script>
export default {
  name: "params",
  computed: {
    userId() {
      return this.$route.params.abc
    }
  }
}
script>


<script>
const routes = [
  {
    path: '/params/:abc',
    name: 'params',
    component: params
  }
]
script>

Vue-cli4——vue-router路由_第4张图片

3.3 参数传递,query

URI = scheme:[//authority]path[?query][#fragment]
通过query传递参数


<h2>{{$route.query.name}}h2>


<router-link :to="{path: '/query', query:{name: '我是query里面的name'}}">queryrouter-link>

Vue-cli4——vue-router路由_第5张图片

3.4 参数传递案例,params与query

通过2个按钮传递数据,一个是用动态路由,一个是用参数传递。

  1. params:通过 params 获取,地址中的 id 数据。
  2. query:对象使用 query 的key作为传递方式

<template>
  <div id="nav">
    <button @click="paramsClick">paramsClickbutton>
    <button @click="queryClick">paramsClickbutton>
  div>
  <router-view/>
template>

<script>
export default {
  name: 'App',
  data() {
    return {
      paramsId: 'params'
    }
  },
  methods:{
    paramsClick(){
      this.$router.push('/params/' + this.paramsId);
    },
    queryClick(){
      this.$router.push({
        path: '/query',
        query:{
          name:'我是属于按钮的query'
        }
      });
    }
  }
}
script>

当我点击paramsClick会出现:
Vue-cli4——vue-router路由_第6张图片

3.5 router与route的区别

我们在开始讲这个区别的时候,首先要知道一件事:所有组件都继承于Vue类的原型

如果我们在Vue的原型上加一个方法,那么所有的组件都可以调用这个方法。

  1. router,向Vue的原型上加的属性
  2. route,输出当前处于活跃的路由,
  3. Vue.prototype.name=“你好”,使用Vue.prototype往Vue的原型添加一个name属性的,在任何地方都可以调用this.name。这种加入和router一样

图中:上面打印的是router,下面是route
在这里我们可以很清楚的看到,router 打印的其实是Vue的原型,而 route 打印的是按钮信息

  1. Vue-cli4——vue-router路由_第7张图片

我们来看下vue-router的一部分源码:src/install.js

  Vue.mixin({
    beforeCreate () {
      if (isDef(this.$options.router)) {
        this._routerRoot = this
        this._router = this.$options.router
        this._router.init(this)
        Vue.util.defineReactive(this, '_route', this._router.history.current)
      } else {
        this._routerRoot = (this.$parent && this.$parent._routerRoot) || this
      }
      registerInstance(this, this)
    },
    destroyed () {
      registerInstance(this)
    }
  })

  Object.defineProperty(Vue.prototype, '$router', {
    get () { return this._routerRoot._router }
  })

  Object.defineProperty(Vue.prototype, '$route', {
    get () { return this._routerRoot._route }
  })

  Vue.component('RouterView', View)
  Vue.component('RouterLink', Link)

我们先来看第18~20行的代码

18~20的结论:

  1. 定义一个属性函数(Object.defineProperty)

  2. 给(Vue.prototype)定义的属性

  3. 属性的键是($router)

  4. 属性的值是(this._routerRoot. _router)

Object.defineProperty //是定义属性函数

Vue.prototype //给这个定义一个属性

$router //属性的键

this._routerRoot._router //属性的值

Vue.prototype.$router = this._routerRoot._router //结果

接下来我们看第3行的:

this.$options,这是指向Vue实例,而后面的:.router而是指向Vue实例里面的router。整段的意思是判断在Vue实例里面有没有router,有就执行下一段代码。

this.$options.router
new Vue({
	el: '#app',
	router
})

第5行的代码:

第一步我们先把刚刚的 route (这个route其实就是Vue实例里面的route)给到 this._ router ,第二步刚刚的 _ router其实就是,等于 this._routerRoot. _router

this._routerRoot = this // 第二步 this.routerRoot._router = this.$options.router
this._router = this.$options.router // 第一步理解先将router给到_router

最后我们看回代码的结果:

Vue.prototype.$router = this._routerRoot._router //第18~20行的代码
this.$options.router // 第3行的代码
this.routerRoot._router = this.$options.router // 第5行的代码

最后我们得出了一个结论:

这个结论需要我们结合刚刚的理解:

  1. 首先我们需要看向第18到20行代码:我们是在Vue实例定义一个属性函数名为($router)

  2. 第二步:他的值是

    this._routerRoot._router
    
  3. 第三步:

    this._routerRoot._router = this.$options.router
    // 而
    this.$options.router
    // 根据第三行的代码得出,他等于VUe实例里面的route
    
  4. 所以,$router永远指向Vue实例的route

最后结论:router是指向Vue实例的router,而route他永远是指向当前活跃的对象,看上面那张图就可以得出这个结论,当按钮被点击时(此时按钮正处于活跃),就返回按钮信息

3.6 全局导航守卫

跳转到某个页面的时候,将该页面的标题改为该页面的名字

to:目标路由对象

from:当前导航将要离开的路由对象

next:调用该方法才能进入下一个钩子

router/index.js

const routes = [
  {
    path: '/test1',
    name: 'test1',
    component: test1,
  }
]
router.beforeEach((to, from, next) =>{
  document.title = to.name
  next()
})

将页面的标题,改为上面routers里面的name

3.7 keep-alive

作用是:避免组件被频繁的销毁创建

通过 activated() 和 beforeRouteLeave()函数实现,保持状态,点击children2后切换到其他页面,在回来还是显示children2。

test1.vue

export default {
  name: "test1",
  data() {
    return {
      message: '你好啊',
      path: '/test1/children1'
    }
  },
  // 这两个函数, 只有该组件被保持了状态使用了keep-alive时, 才是有效的
		activated() {
      this.$router.push(this.path);
      console.log('activated');
    },
    deactivated() {
      console.log('deactivated');
    },
  beforeRouteLeave (to, from, next) {
    console.log(this.$route.path);
    this.path = this.$route.path;
    next()
  }
}

App.vue

  
    
      
    
  

有些时候我们希望离开某个组件的时候,该组件不被缓存,我们可以使用 exclude

  • Props

    • include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
    • exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
    • max - 数字。最多可以缓存多少组件实例。

    这里的test2指向例外一个页面,test2页面被创建,点击test1时,test1页面被创建而test2页面被销毁,在点回test2页面 test2页面被创建。

  
    
      
    
  

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R0xEU5NM-1605677649829)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201118130820009.png)]

总结

你可能感兴趣的:(Vue,vue)