Vue Router用法与基础

1/9/2022 Vuevue-router

# Vue Router基础回顾

当我们使用vue-cli创建项目的时候,选择项目特性时选择Router,会自动安装Vue Router插件并且生成Vue Router的基础代码结构。

  • 创建路由视图(插件)
  • 注册路由组件
  • 创建路由对象
  • 注册router对象,<router-view/><router-link>完成模板配置

# 实现步骤

  1. 下载模板
  • views视图文件夹中有几个和路由相关的vue文件
  • router文件夹是路由模块
  • main.js是项目入口文件
  • App.vue主模板
  1. 在index.js中首先导入vue和vue-router,并且通过vue调用use方法注册路由组件
// 导入vue和vue-router
import Vue from 'vue'
import VueRouter from 'vue-router'
import Index from '../views/Index.vue'
// 1. vue调用use方法注册路由组件
Vue.use(VueRouter)
1
2
3
4
5
6

Vue.use(VueRouter) Vue.use是用来注册插件的,它里面需要接收一个参数。

  • 如果参数是函数的话,use内部会直接调用函数注册组件
  • 如果传入的是对象的话,它会调用传入对象的install方法来注册插件。
  1. 注册路由规则,定义一个对象数组,对象就是我们对应的路由规则。路由组件对应路径,路径变化的时候会加载相应的组件。
  • path:路由路径
  • name:路由名称
  • component:路径对应组件
const routes = [
  {
    path: '/',
    name: 'Index',
    component: Index
  },
  {
    path: '/blog',
    name: 'Blog',
    ...
  }
  ...
]
1
2
3
4
5
6
7
8
9
10
11
12
13
  1. 创建路由对象,通过new VueRouter来创建一个router对象,创建的时候把路由规则传入,最后将路由对象导出。
const router = new VueRouter({
  routes
})
export default router
1
2
3
4
  1. 在main.js中导入router对象,并在创建Vue实例的时候注册router对象
import Vue from 'vue'
import App from './App.vue'
// 导入router对象
import router from './router'

Vue.config.productionTip = false

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

这里传入router的作用:(这里可以通过打印new Vue那个vue实例在控制台中看到区别)

当我们创建vue实例的时候,配置router时它会给实例分别注册$route$router属性

  • $route是路由规则
  • $router是VueRouter实例,路由对象,里面会提供一些和路由相关的方法(例如:router.push()、router.replace()、router.go()),和路由的相关信息(mode模式,currentRoute)
  • hash模式:路径中用井号方式表示
  • currentRoute : 当前路由规则(有时候我们无法获取$route,但是可以获取$router,如果获取到了$router就可以根据currentRoute获取当前路由规则)
  1. App.vue中会创建一个<router-view/>的模板,这个<router-view/>的作用是组件的占位符,当路径匹配到组件后会把一个组件加载进来,并且会替换<router-view/>,并且通过<router-link>创建一些链接
<template>
  <div id="app">
    <div>
      <img src="@/assets/logo.png" alt="">
    </div>
    <div id="nav">
      <!-- 通过router-link创建链接 -->
      <router-link to="/">Index</router-link> |
      <router-link to="/blog">Blog</router-link> |
      <router-link to="/photo">Photo</router-link>
    </div>
    <!-- 通过router-view创建路由组件的占位 -->
    <router-view/>
  </div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  1. 命令行输入npm run serve可以正常运行。

# 动态路由

  1. 下载模板
  2. 在router/index.js中,路由配置里,:id就是通过占位符匹配变化的位置,实现动态路由。
const routes = [
  // 首页是固定的/,加载Index组件
  {
    path: '/',
    name: 'Index',
    // 固定路由直接加兹组件
    component: Index
  },
  // 不同的详情页需要传id,后面的:id是占位符,将来在使用的时候要传入对象商品的id,这个就是动态路由
  {
    path: '/detail/:id',
    name: 'Detail',
    props: true,
    // 使用路由懒加载,用户访问对应路由地址的时候才会下载对应的路由组件,如果不访问组件不会被加载,提高程序性能
    component: () => import(/* webpackChunkName: "detail" */ '../views/Detail.vue')
  }
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  1. 组件如何接收参数

方式一:使用$router获取params

这种方式不太好,因为当前组件强依赖于路由,使用的时候路由必须传递相应的参数。

```html
<template>
  <div>
    <!-- 方式1: 通过当前路由规则,获取数据 -->
    通过当前路由规则获取:
  </div>
</template>
```

方式二:配置props (推荐)

  • 在router/index.js中配置开启props
// router/index.js
const routes = [
  {
    path: '/detail/:id',
    name: 'Detail',
    // 开启 props,会把 URL 中的参数传递给相应组件
    // 在组件中通过 props 来接收 URL 参数,和父子组件传值的方式相同
    props: true,
    component: () => import(/* webpackChunkName: "detail" */ '../views/Detail.vue')
  }
]
1
2
3
4
5
6
7
8
9
10
11
  • 在子组件中使用id
<template>
  <div>
    <!-- 方式2:路由规则中开启 props 传参 -->
    通过开启 props 获取:{{ id }}
  </div>
</template>

<script>
export default {
  name: 'Detail',
  // 通过props获取id
  props: ['id']
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 嵌套路由

当多个路由组件都有相同的内容,我们可以把相同的内容都提取到一个公共的组件中。

image

如果首页和详情页都有相同的Header和Footer,把相同的东西提取出来,做成一个Layout组件。其中变化的位置就用<router-view>占位。

之后我们访问首页的时候,它会将首页和Layout合并输出。

  1. 下载模板
  2. 可以看到在components/Layout.vue文件中,加载的时候先加载Layout组件,然后加载首页的时候替换掉router-view。
<template>
  <div>
  <!--Header:图片-->
    <div>
      <img width="25%" src="@/assets/logo.png">
    </div>
    <!--中间不同的地方-->
    <div>
      <router-view></router-view>
    </div>
    <!--Footer-->
    <div>
      Footer
    </div>
  </div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  1. views里面的Login.vue组件是不需要头和尾的,那如何配置路由呢?
const routes = [
  // login是正常路由
  {
    name: 'login',
    path: '/login',
    component: Login
  },
  // 嵌套路由
  {
    // 访问/ 根目录的时候会先加载Layout
    path: '/',
    component: Layout,
    children: [
      {
        name: 'index',
        // children里的路径可以是先谷底路径也可以是绝对路径
        path: '',
        component: Index
      },
      {
        name: 'detail',
        // 相对路径,外部路径+里面路径 /detail/:id
        path: 'detail/:id',
        props: true,
        component: () =>
        // 动态加载,使用的时候再加载模块
        import('@/views/Detail.vue')
      }
    ]
  }
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 编程式导航

之前页面跳转的时候,使用的是router-link生成超链接。登录页面是要点击按钮跳转首页,这里就用到编程式导航,$router.push方法。

  • $router.push()

跳转路由,里面传参可以有两种路由方式

  • 直接传跳转地址:this.$router.push('/'),
  • 跳转路由名称:this.$router.push({ name: 'Home' })

添加参数

  • 直接传完整跳转地址:this.$router.push('/detail/1'),
  • 跳转路由名称+跳转参数:this.$router.push({ name: 'Detail', params: { id: 1 } })
  • $router.replace()

replace方法和push方法都可以跳转到指定页面,参数内容也是一样的。

但是replace会替换跳转历史,会把上次的历史删除后替换掉。

  • $router.go()

go方法可以指定跳转到历史中的某一次,可以是负数,表示后退

go(-1) 与 back()的效果是一样的,表示后退到上一次访问的页面

  1. 下载模板
  2. views/login.vue组件代码使用$router.push()
<template>
  <div>
    用户名:<input type="text" /><br />&nbsp;&nbsp;码:<input type="password" /><br />

    <button @click="push"> push </button>
  </div>
</template>

<script>
export default {
  name: 'Login',
  methods: {
    push () {
      // 第一种方式是字符串,即跳转的路由地址
      this.$router.push('/')
      // 第二种方式是传对象,指定路由名称,这个name就是路由规则中命名的名字
      // this.$router.push({ name: 'Home' })
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  1. views/index.vue中$router.push的用法
<template>
  <div class="home">
    <div id="nav">
      <router-link to="/">Index</router-link>
    </div>
    <button @click="replace"> replace </button>

    <button @click="goDetail"> Detail </button>
  </div>
</template>

<script>
export default {
  name: 'Index',
  methods: {
    // replace方法和push方法都可以跳转到指定页面,参数内容也是一样的。
    // replace不会记录本次历史,它会把当前历史改成/login
    replace () {
      this.$router.replace('/login')
    },
    // 这个使用push,并传递了参数,使用params传一个对象,键值就是路由参数
    goDetail () {
      this.$router.push({ name: 'Detail', params: { id: 1 } })
    }
  }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  1. views/Detail.vue中使用
<template>
  <div>
    路由参数:{{ id }}

    <button @click="go"> go(-2) </button>
  </div>
</template>

<script>
export default {
  name: 'Detail',
  props: ['id'],
  methods: {
    // go方法可以指定跳转到历史中的某一次,可以是负数,表示后退
    // go(-1) 与 back()的效果是一样的,表示后退到上一次访问的页面
    go () {
      this.$router.go(-2)
    }
  }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  1. 命令行中执行npm run serve,可以感受跳转的不同。
更新时间: 2022-01-10 09:52