您当前的位置: 首页 > 

HM-hhxx!

暂无认证

  • 5浏览

    0关注

    123博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

VUE-路由详解

HM-hhxx! 发布时间:2022-05-14 19:36:13 ,浏览量:5

目录

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子组件,我们在点击跳转按钮的时候,页面通过 改变了,但是地址url没变,这就是单页面应用。

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

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

2.起步

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

HTML




Hello App!

Go to Foo Go to Bar

JavaScript

// 0. 如果使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter)

// 1. 定义 (路由) 组件。
// 可以从其他文件 import 进来
const Foo = { template: '
foo
' } const Bar = { template: '
bar
' } // 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 的原因是我们并不想在每个独立需要封装路由的组件中都导入路由。

要注意,当 对应的路由匹配成功,将自动设置 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对应的组件应该显示的位置。

{{nav.text}}
4.router-link属性

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

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


{{nav.text}}

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

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

登陆

 

5.动态路由匹配

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

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

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

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

const User = {
  template: '
User {{ $route.params.id }}
' }

你可以在一个路由中设置多段“路径参数”,对应的值都会设置到 $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中加入即可。

给路由起别名

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

起别名的方式就是往路由匹配规则加个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就是动态的:

{{nav.text}}

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

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

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

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

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

接着上节创建的 app:

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

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

const User = {
  template: `
    
User {{ $route.params.id }}
` }

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

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

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

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

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

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

        // ...其他子路由
      ]
    }
  ]
})
7.编程式的导航

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

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

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

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

当你点击 时,这个方法会在内部调用,所以说,点击 等同于调用 router.push(...)

声明式编程式

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)

关注
打赏
1663160980
查看更多评论
立即登录/注册

微信扫码登录

0.2966s