VUE-路由详解

目录

1.什么是路由?

2.起步

3.路由的基本使用

4.router-link属性

5.动态路由匹配

5.1响应路由参数的变化

5.2捕获所有路由或 404 Not found 路由

5.3高级的匹配模式

5.4匹配优先级

6.嵌套路由

7.编程式的导航

7.1router.push(location, onComplete?, onAbort?)

7.2router.replace(location, onComplete?, onAbort?)

7.3router.go(n)


1.什么是路由?

后端路由:对于普通的网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上对应的资源;

前端路由:对于单页面应用程序来说,主要通过URL中的hash(#号)来实现不同页面之间的切换,并不会向后端发送请求。同时,hash有一个特点:HTTP请求中不会包含hash相关的内容;所以,单页面程序中的页面跳转主要用hash实现;

在单页面应用程序中,这种通过hash改变来切换页面的方式,称作前端路由(区别于后端路由);

承接到Vue的组件的示例文件:👇

现在有Home,Goods和Users子组件,我们在点击跳转按钮的时候,页面通过<Component :is="currentPage" /> 改变了,但是地址url没变,这就是单页面应用。

这样有一个问题就是没法分享给他人,因为地址是相同的,但是看到的内容不同。还有一点就是没有回退功能。

如何解决这个问题?及用到了vue的路由。

2.起步

用 Vue.js + Vue Router 创建单页应用,感觉很自然:使用 Vue.js ,我们已经可以通过组合组件来组成应用程序,当你要把 Vue Router 添加进来,我们需要做的是,将组件 (components) 映射到路由 (routes),然后告诉 Vue Router 在哪里渲染它们。下面是个基本例子:

HTML

<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

<div id="app">
  <h1>Hello App!</h1>
  <p>
    <!-- 使用 router-link 组件来导航. -->
    <!-- 通过传入 `to` 属性指定链接. -->
    <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
    <router-link to="/foo">Go to Foo</router-link>
    <router-link to="/bar">Go to Bar</router-link>
  </p>
  <!-- 路由出口 -->
  <!-- 路由匹配到的组件将渲染在这里 -->
  <router-view></router-view>
</div>

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')

// 现在,应用已经启动了!

通过注入路由器,我们可以在任何组件内通过 this.$router 访问路由器,也可以通过 this.$route 访问当前路由:

// Home.vue
export default {
  computed: {
    username() {
      // 我们很快就会看到 `params` 是什么
      return this.$route.params.username
    }
  },
  methods: {
    goBack() {
      window.history.length > 1 ? this.$router.go(-1) : this.$router.push('/')
    }
  }
}

该文档通篇都常使用 router 实例。留意一下 this.$routerrouter 使用起来完全一样。我们使用 this.$router 的原因是我们并不想在每个独立需要封装路由的组件中都导入路由。

要注意,当 <router-link> 对应的路由匹配成功,将自动设置 class 属性值 .router-link-active

3.路由的基本使用

在vue中使用路由需要用到vue-router的插件。

1、按照vue-router插件

npm i vue-router -S

 2、引入并注入路由到vue

import Router from 'vue-router'

Vue.use(Router);

 3、创建一个路由实例,参数为一个对象,这个配置对象中有一个属性:routes,表示 路由的匹配规则

let router = new Router({
    routes : [
        { path: '/home', component: Home }, //当地址为/home时,显示Home组件
        { path: '/goods', component: Goods },
        { path: '/users', component: Users }
    ]
});

routes 属性是一个数组,数组中的每一项都是一条匹配规则。

每个路由规则,都是一个对象,这个规则对象,身上,有两个必须的属性:

path:表示监听的路由链接地址

component:表示如果路由是前面匹配到的 path ,则展示 component 属性对应的那个组件。

4、将路由规则对象router注册到vue实例

new Vue({
  el: "#box",
  data: {},
  methods: {},
  // 将路由对象注册到vue实例
  router
});

 5、一旦路由规则匹配成功,就会在vue-router 提供的标签router-view 上显示出来,这个标签就是匹配路由成功后component对应的组件应该显示的位置。

<div>
    <button @click="goPage(nav.name)" v-for="nav in navs">{{nav.text}}</button>
    <router-view></router-view>
</div>

4.router-link属性

我们之前的超链接是由a标签代替的,如果要跳转那么并且每次href属性都要加上#,这样太麻烦。

vue-router官方提供了一个router-link 的属性可以实现路由的跳转。

<!--app.html-->
<div>
    <router-link tag="button" :to="nav.name" v-for="nav in navs">{{nav.text}}</router-link>
    <router-view></router-view>
</div>

 我们通过检查可以知道,router-link 会默认渲染为一个a 标签。

但是我们也可以将其改变成别的标签,使用 tag="span" 属性可以将默认的a标签转换成span标签:

<router-link to="/login" tag="span">登陆</router-link>

 

5.动态路由匹配

我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个 User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在 vue-router 的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果:

const User = {
  template: '<div>User</div>'
}

const router = new VueRouter({
  routes: [
    // 动态路径参数 以冒号开头
    { path: '/user/:id', component: User }
  ]
})

现在呢,像 /user/foo/user/bar 都将映射到相同的路由。

一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到 this.$route.params,可以在每个组件内使用。于是,我们可以更新 User 的模板,输出当前用户的 ID:

const User = {
  template: '<div>User {{ $route.params.id }}</div>'
}

你可以在一个路由中设置多段“路径参数”,对应的值都会设置到 $route.params 中。例如:

模式

匹配路径

$route.params

/user/:username

/user/evan

{ username: 'evan' }

/user/:username/post/:post_id

/user/evan/post/123

{ username: 'evan', post_id: '123' }

除了 $route.params 外,$route 对象还提供了其它有用的信息,例如,$route.query (如果 URL 中有查询参数)、$route.hash 等等。

5.1响应路由参数的变化

提醒一下,当使用路由参数时,例如从 /user/foo 导航到 /user/bar原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用

复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch (监测变化) $route 对象:

const User = {
  template: '...',
  watch: {
    $route(to, from) {
      // 对路由变化作出响应...
    }
  }
}

或者使用 2.2 中引入的 beforeRouteUpdate 导航守卫

const User = {
  template: '...',
  beforeRouteUpdate(to, from, next) {
    // react to route changes...
    // don't forget to call next()
  }
}

5.2捕获所有路由或 404 Not found 路由

常规参数只会匹配被 / 分隔的 URL 片段中的字符。如果想匹配任意路径,我们可以使用通配符 (*):

{
  // 会匹配所有路径
  path: '*'
}
{
  // 会匹配以 `/user-` 开头的任意路径
  path: '/user-*'
}

当使用通配符路由时,请确保路由的顺序是正确的,也就是说含有通配符的路由应该放在最后。路由 { path: '*' } 通常用于客户端 404 错误。如果你使用了History 模式,请确保正确配置你的服务器

当使用一个通配符时,$route.params 内会自动添加一个名为 pathMatch 参数。它包含了 URL 通过通配符被匹配的部分:

// 给出一个路由 { path: '/user-*' }
this.$router.push('/user-admin')
this.$route.params.pathMatch // 'admin'
// 给出一个路由 { path: '*' }
this.$router.push('/non-existing')
this.$route.params.pathMatch // '/non-existing'

5.3高级的匹配模式

vue-router 使用 path-to-regexp (opens new window)作为路径匹配引擎,所以支持很多高级的匹配模式,例如:可选的动态路径参数、匹配零个或多个、一个或多个,甚至是自定义正则匹配。查看它的文档 (opens new window)学习高阶的路径匹配,还有这个例子 (opens new window)展示 vue-router 怎么使用这类匹配。

5.4匹配优先级

有时候,同一个路径可以匹配多个路由,此时,匹配的优先级就按照路由的定义顺序:路由定义得越早,优先级就越高。

6.嵌套路由

 我们现在想在/home路径下再接子路由a和b,形成嵌套路由/home/a或者/home/b形式的路由。

在路由配置规则数组中使用 children 属性,实现子路由功能。

let router = new Router({
    routes: [
        // 路由重定向
        { path: '/', redirect: '/home' },
        {
            path: '/home',
            component: Home,
        	// 使用children实现子路由
            children: [
                { path: 'a', component: A },
                { path: 'b', component: B }
            ]
        },
        { path: '/goods', component: Goods },
        { path: '/users', component: Users }
    ]
});

注意:子路由的匹配规则前面不要加 /

然后在Home的template中加入<router-view></router-view>即可。

给路由起别名

我们还可以给路由起个别名,这样在有些路由特别长的时候就很方便。

起别名的方式就是往路由匹配规则加个name属性即可。

let router = new Router({
    routes: [
        { path: '/', redirect: '/home' },
        {
            path: '/home',
            component: Home,
            name: 'h',
            children: [
                { path: 'a', component: A, name: 'a' },
                { path: 'b', component: B, name: 'b' }
            ]
        }, //当地址为/home时,显示Home组件
        { path: '/goods', component: Goods, name: 'g' },
        { path: '/users', component: Users, name: 'u' }
    ]
});

那么我们在使用router-link跳转的时候,属性to就是动态的:

<router-link tag="button" :to="{name:'a'}" v-for="nav in navs">{{nav.text}}</router-link>

然后重定向redirect也可以使用name:

{ path: '/', redirect: {name:'h'} },

实际生活中的应用界面,通常由多层嵌套的组件组合而成。同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件,例如:

/user/foo/profile                     /user/foo/posts
+------------------+                  +-----------------+
| User             |                  | User            |
| +--------------+ |                  | +-------------+ |
| | Profile      | |  +------------>  | | Posts       | |
| |              | |                  | |             | |
| +--------------+ |                  | +-------------+ |
+------------------+                  +-----------------+

借助 vue-router,使用嵌套路由配置,就可以很简单地表达这种关系。

接着上节创建的 app:

<div id="app">
  <router-view></router-view>
</div>
const User = {
  template: '<div>User {{ $route.params.id }}</div>'
}

const router = new VueRouter({
  routes: [{ path: '/user/:id', component: User }]
})

这里的 <router-view> 是最顶层的出口,渲染最高级路由匹配到的组件。同样地,一个被渲染组件同样可以包含自己的嵌套 <router-view>。例如,在 User 组件的模板添加一个 <router-view>

const User = {
  template: `
    <div class="user">
      <h2>User {{ $route.params.id }}</h2>
      <router-view></router-view>
    </div>
  `
}

要在嵌套的出口中渲染组件,需要在 VueRouter 的参数中使用 children 配置:

const router = new VueRouter({
  routes: [
    {
      path: '/user/:id',
      component: User,
      children: [
        {
          // 当 /user/:id/profile 匹配成功,
          // UserProfile 会被渲染在 User 的 <router-view> 中
          path: 'profile',
          component: UserProfile
        },
        {
          // 当 /user/:id/posts 匹配成功
          // UserPosts 会被渲染在 User 的 <router-view> 中
          path: 'posts',
          component: UserPosts
        }
      ]
    }
  ]
})

要注意,以 / 开头的嵌套路径会被当作根路径。 这让你充分的使用嵌套组件而无须设置嵌套的路径。

你会发现,children 配置就是像 routes 配置一样的路由配置数组,所以呢,你可以嵌套多层路由。

此时,基于上面的配置,当你访问 /user/foo 时,User 的出口是不会渲染任何东西,这是因为没有匹配到合适的子路由。如果你想要渲染点什么,可以提供一个 空的 子路由:

const router = new VueRouter({
  routes: [
    {
      path: '/user/:id',
      component: User,
      children: [
        // 当 /user/:id 匹配成功,
        // UserHome 会被渲染在 User 的 <router-view> 中
        { path: '', component: UserHome }

        // ...其他子路由
      ]
    }
  ]
})

7.编程式的导航

除了使用 <router-link> 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。

7.1router.push(location, onComplete?, onAbort?)

 注意:在 Vue 实例内部,你可以通过 $router 访问路由实例。因此你可以调用 this.$router.push

想要导航到不同的 URL,则使用 router.push 方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。

当你点击 <router-link> 时,这个方法会在内部调用,所以说,点击 <router-link :to="..."> 等同于调用 router.push(...)

声明式编程式

<router-link :to="...">

router.push(...)

该方法的参数可以是一个字符串路径,或者一个描述地址的对象。例如:

// 字符串
router.push('home')

// 对象
router.push({ path: 'home' })

// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})

// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})

注意:如果提供了 pathparams 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path

const userId = '123'
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user

同样的规则也适用于 router-link 组件的 to 属性。

在 2.2.0+,可选的在 router.pushrouter.replace 中提供 onCompleteonAbort 回调作为第二个和第三个参数。这些回调将会在导航成功完成 (在所有的异步钩子被解析之后) 或终止 (导航到相同的路由、或在当前导航完成之前导航到另一个不同的路由) 的时候进行相应的调用。在 3.1.0+,可以省略第二个和第三个参数,此时如果支持 Promise,router.pushrouter.replace 将返回一个 Promise。

注意: 如果目的地和当前路由相同,只有参数发生了改变 (比如从一个用户资料到另一个 /users/1 -> /users/2),你需要使用 beforeRouteUpdate 来响应这个变化 (比如抓取用户信息)。

7.2router.replace(location, onComplete?, onAbort?)

router.push 很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。

7.3router.go(n)

这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)

// 在浏览器记录中前进一步,等同于 history.forward()
router.go(1)

// 后退一步记录,等同于 history.back()
router.go(-1)

// 前进 3 步记录
router.go(3)

// 如果 history 记录不够用,那就默默地失败呗
router.go(-100)
router.go(100)

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Vue Router 是 Vue.js 官方的路由管理器,它和 Vue.js 的核心深度集成,让构建单页应用变得易如反掌。Vue Router 通过管理应用的URL,实现了组件的切换,让用户可以在单页应用中享受到和传统多页应用相同的体验。 在 Vue Router 中,我们可以通过 <router-view> 组件来渲染匹配到的组件。它是 Vue Router 中最重要的组件之一。当我们的路由切换时,<router-view> 组件可以根据当前的 URL 自动切换到匹配到的组件,不需要手动处理。 下面是一些关于 <router-view> 组件使用的详解: 1. <router-view> 组件是函数式组件,它不会渲染出任何实际的 HTML 元素,而是渲染出匹配到的组件。 2. 每次路由切换时,<router-view> 组件会销毁旧的组件并创建新的组件实例。 3. 如果在路由配置中没有指定组件的 name 属性,则默认使用默认组件。 4. 如果有多个 <router-view> 组件,需要在路由配置中指定每个 <router-view> 组件应该渲染哪个组件。 5. 如果没有匹配到任何路由,则 <router-view> 组件不会渲染出任何内容。 6. 可以使用 <keep-alive> 包裹 <router-view> 组件,让路由切换时保持组件状态不被销毁。 7. 可以使用 <transition> 包裹 <router-view> 组件,为路由切换添加过渡动画效果。 总的来说,<router-view> 组件是 Vue Router 中最常用的组件之一。它可以让我们在构建单页应用时轻松地管理路由和组件,为用户提供更好的体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HM-hhxx!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值