VUE复习笔记29(vue-router详解基础)

安装

1.直接下载/cdn
https://unpkg.com/vue-router/dist/vue-router.js

Unpkg.com提供基于npm的CDN链接。以上链接将始终指向npm上的最新版本。您还可以通过URL等使用特定版本/标签https://unpkg.com/vue-router@2.0.0/dist/vue-router.js

<script src="/path/to/vue.js"></script>
<script src="/path/to/vue-router.js"></script>

2.NPM安装,一般推荐使用这种
一般其实我们在构建 vue 应用的时候就可以选择默认把他先安装上去。

npm install vue-router

模块系统一起使用时,必须通过Vue.use()以下方式显式安装路由器:

//引入相关文件,使用Vue.use()即可
import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

介绍

Vue Router是VueJs的官方路由器,他与vuejs核心,深度集成,使用它构建单页面应用会变得轻而易举。

功能介绍

嵌套路由/视图映射
模块化,基于组件的路由器配置
路线参数,查询,通配符
查看由Vue.js过渡系统提供支持的过渡效果
细粒度的导航控制
与自动活动CSS类的链接
HTML5历史模式或哈希模式,在IE9中具有自动回退功能
可自定义的滚动行为

入门

使用Vue + Vue路由器创建单页应用程序非常简单。使用Vue.js,我们已经在使用组件编写应用程序。将Vue Router添加到混合中时,我们需要做的就是将组件映射到路由,让Vue Router知道在哪里渲染它们。这是一个基本的例子:

route-link

可以看作是导航链接点击去定制页面
to中的路径是导航 url 中的页面路径,并非项目路径。
注意:路径必须在 index.js中已经配置完毕

    <router-link to="/">go home</router-link>
    <router-link to="/school">go school</router-link>

HTML

app.vue中添加 route-view标签用来切换视图

<template>
<div id="app">
    <router-view>
      
    </router-view>
</div>
</template>
//home.vue作为我们的首页
<template>
    <div class="home">
        <h2>home</h2>
    </div>
</template>

<script>
    export default{
        data(){
            return{

            }
        }
    }
</script>

在router文件夹下的index.js修改
引入home和其他页面,进行配置路由路径

import Vue from 'vue'
import Router from 'vue-router'
import home from '../pages/home'

Vue.use(Router)

const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }

export default new Router({
  routes: [
    {
      path:'/',
      name:'home',
      component:home
    },
    {
      path: '/foo',
      name: 'Foo',
      component: Foo
    },
    {
      path: '/bar',
      name: 'Bar',
      component: Bar
    }
  ]
})

我们通过在home.vue中打印 console.log(this.$route),可以查看路由对象的内容。

image.png

根据以上实例就能在不同的 url下切换页面了。

动态路由匹配

我们经常需要将具有给定模式的路线映射到同一个组件。例如,我们可能有一个User应该为所有用户呈现但具有不同用户ID的组件。在vue-router我们可以在路径中使用动态段以实现:

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

const router = new VueRouter({
  routes: [
    // dynamic segments start with a colon
    { path: '/user/:id', component: User }
  ]
})

动态段由冒号表示,匹配路径的时候,动态段的字段 (这里的id)this.$router.params.id,将会向每一个组件中公开,我们可以进行取值获得 id。

image.png

上图就是直接在 div中获取了,动态字段
User {{ $route.params.id }}

另外我们还可以在动态字段后面继续添加动态段。如图:


image.png

除此之外$route.params,该$route对象还公开了其他有用的信息,例如$route.query(如果URL中有查询)$route.hash等。您可以在API参考中查看完整的详细信息

对params更改作出反应

意思是仅仅对动态段内容的修改做出反应,如上面提到的 /user/:id 中的id的变化。

从id1 到id2的变化,会重用相同的组件实例。由于两个路由都是相同的组件 user,因此这比销毁旧实例,创建新实例更有效。既然是重用原来的组件,也就意味着不会调用生命周期钩子函数。因为生命周期钩子函数只会在一个组件从无到有的过程中产生。

要对 同一个组件的 params 的更改作出反应,我们只需要观察 $router 对象就可以了。

const User = {
  template: '...',
  watch: {
    '$route' (to, from) {
      // react to route changes...
    }
  }
}

或者,使用2.2中介绍的beforeRouteUpdate 导航防护

const User = { 
  template:'<div>User {{ $route.params.id }}</div>' ,
  watch:{
    '$route'(to,from){
      console.log(to)
      console.log(from)
      //其中 to 代表新的修改后内容,from代表之前的
    }
  }
}

image.png

上图可看到:
/user/123456 是我们新修改的
/user/12345 是我们原来的id

高级匹配模式

vue-router使用path-to-regexp作为其路径匹配引擎,因此它支持许多高级匹配模式,例如可选动态段,零个或多个/一个或多个要求,甚至自定义正则表达式模式。查看这些高级模式的文档,以及使用它们的示例vue-router

匹配优先级

有时,多个路由可能会匹配相同的URL。在这种情况下,匹配优先级由路由定义的顺序确定:路由定义越早,它获得的优先级越高。
而且并不会被后面的路由覆盖。

嵌套路由

真正的应用程序UI通常嵌套多个级别的组件组成,url的每一段 对应着嵌套组件的结构也是很常见的。

image.png

有了 vue-router,使用嵌套路由来表达就容易了很多。

我们还是使用之前创建的应用程式。

<div id="app">
  <router-view></router-view>
</div>
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
const User = { 
  template:'<div>User {{ $route.params.id }}</div>' ,
  watch:{
    '$route'(to,from){
      console.log(to)
      console.log(from)
    }
  }
}

export default new Router({
  routes: [
    {
      path:'/',
      name:'home',
      component:home
    },
    {
      path: '/foo',
      name: 'Foo',
      component: Foo
    },
    {
      path: '/bar',
      name: 'Bar',
      component: Bar
    },
    {
      path:'/user/:id',
      component:User
    }
  ]
})

app.vue中的route-view是一个顶级出口,同样,渲染组件也可以包含自己的嵌套组件<router-view>。例如,如果我们在User组件的模板中添加一个:

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

现在我们已经在 user 组件中添加了一个 route-view 的模块。
如果想要把内容放进去的话,我们需要在 VueRouter中添加一个 children 选项。

修改 index.js后如下:

import Vue from 'vue'
import Router from 'vue-router'
import home from '../pages/home'

Vue.use(Router)

const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
const child1 = { template: '<div>child1</div>' }
const child2 = { template: '<div>child2</div>' }
const User = { 
  template:
    `<div class="user">
      <h2>User {{ $route.params.id }}</h2>
      <router-view></router-view>
    </div>` ,
  watch:{
    '$route'(to,from){
      console.log(to)
      console.log(from)
    }
  }
}

export default new Router({
  routes: [
    {
      path:'/',
      name:'home',
      component:home
    },
    {
      path: '/foo',
      name: 'Foo',
      component: Foo
    },
    {
      path: '/bar',
      name: 'Bar',
      component: Bar
    },
    {
      path:'/user/:id',
      component:User,
      children:[
        {
          path: 'child1',
          component: child1
        },
        {
          path: 'child2',
          component: child2
        }
      ]
    }
  ]
})

结果如下:


image.png

程序化导航

除了使用<router-link>为声明性导航创建锚标签之外,我们可以使用路由器的实例方法以编程方式执行此操作。也就是在js中操作路由。

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

我们在Vue实例的内部可以访问路由的实例 $router。因此你可以调用this.$router.push
想要导航到不同的 URL,则使用 router.push 方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。

当我们设置好route-link时,这方法会内部自动嗲用,所以说,点击 <router-link :to="...">等同于调用 router.push(...)

image.png

this.$router.push(location, onComplete?, onAbort?)

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

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

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

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

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

注意:如果提供了 path,params 会被忽略,上述例子中的 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

操作History

你也许注意到 router.pushrouter.replacerouter.gowindow.history.pushStatewindow.history.replaceStatewindow.history.go好像, 实际上它们确实是效仿 window.historyAPI 的。

因此,如果你已经熟悉 Browser History APIs,那么在 Vue Router 中操作 history 就是超级简单的。

还有值得提及的,Vue Router 的导航方法 (pushreplacego) 在各类路由模式 (historyhashabstract) 下表现一致。

思考

vue 中router.gorouter.pushrouter.replace的区别

router.go(n)

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

router.push(location)

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

router.replace(location)

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 198,030评论 5 464
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,198评论 2 375
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 144,995评论 0 327
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,973评论 1 268
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,869评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,766评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,967评论 3 388
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,599评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,886评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,901评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,728评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,504评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,967评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,128评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,445评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,018评论 2 343
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,224评论 2 339

推荐阅读更多精彩内容