vue-router 基础

安装

NPM

  • npm install vue-router

  • 如果在一个模块化工程中使用它,必须要通过 Vue.use() 明确地安装路由功能:

      import Vue from 'vue'
      import VueRouter from 'vue-router'
      
      Vue.use(VueRouter)
    
  • 如果使用全局的 script 标签,则无须如此(手动安装)。

开始

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

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

动态路由匹配

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

      const User = {
        template: '<div>User</div>'
      }
    
      const router = new VueRouter({
        routes: [
          // 动态路径参数 以冒号开头
          { path: '/user/:id', component: User }
        ]
      })
    
  • 在一个路由中设置多段『路径参数』,对应的值都会设置到 $route.params 中

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

编程式的导航

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

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

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

  • 当你点击 时,这个方法会在内部调用,所以说,点击 等同于调用 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' }})
    

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

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

      声明式	                              编程式
      <router-link :to="..." replace>	    router.replace(...)
    

router.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)
    

操作History

  • router.push、 router.replace 和 router.go 跟 window.history.pushState、 window.history.replaceState 和 window.history.go好像, 实际上它们确实是效仿 window.history API 的。
  • vue-router 的导航方法 (push、 replace、 go) 在各类路由模式(history、 hash 和 abstract)下表现一致。

命名路由

const router = new VueRouter({
  routes: [
    {
      path: '/user/:userId',
      name: 'user',
      component: User
    }
  ]
})
  • 要链接到一个命名路由,可以给 router-link 的 to 属性传一个对象:

      <router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
    
  • 这跟代码调用 router.push() 是一回事:

      router.push({ name: 'user', params: { userId: 123 }})
    
  • 这两种方式都会把路由导航到 /user/123 路径。

命名视图

  • 如果router-view没有设置名字,那么默认为default

      <router-view class="view one"></router-view>
      <router-view class="view two" name="a"></router-view>
      <router-view class="view three" name="b"></router-view>
    
  • 一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components 配置(带上 s):

      const router = new VueRouter({
        routes: [
          {
            path: '/',
            components: {
              default: Foo,
              a: Bar,
              b: Baz
            }
          }
        ]
      })
    

嵌套命名视图

/settings/emails                                       /settings/profile
+-----------------------------------+                  +------------------------------+
| UserSettings                      |                  | UserSettings                 |
| +-----+-------------------------+ |                  | +-----+--------------------+ |
| | Nav | UserEmailsSubscriptions | |  +------------>  | | Nav | UserProfile        | |
| |     +-------------------------+ |                  | |     +--------------------+ |
| |     |                         | |                  | |     | UserProfilePreview | |
| +-----+-------------------------+ |                  | +-----+--------------------+ |
+-----------------------------------+                  +------------------------------+
  • Nav 只是一个常规组件。
  • UserSettings 是一个视图组件。
  • UserEmailsSubscriptions、UserProfile、UserProfilePreview 是嵌套的视图组件。

路由组件传参

使用props将组件和路由解耦

取代与$route的耦合

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

通过props解耦

const User = {
  props: ['id'],
  template: '<div>User {{ id }}</div>'
}
const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User, props: true },

    // 对于包含命名视图的路由,你必须分别为每个命名视图添加 `props` 选项:
    {
      path: '/user/:id',
      components: { default: User, sidebar: Sidebar },
      props: { default: true, sidebar: false }
    }
  ]
})

布尔模式

  • 如果props被设置为true,route.params将会被设置为组件属性

对象模式

  • 如果props是一个对象,它会被按原样设置为组件属性。当props是静态的时候有用

      const router = new VueRouter({
        routes: [
          { 
      		path: '/promotion/from-newsletter', 
      		component: Promotion,
      	    props: { 
      			newsletterPopup: false
      		 }
      	}
        ]
      })
    

函数模式

  • 可以创建一个函数返回props。这样你便可以将参数转换成另一种类型,将静态值与基于路由的值结合等等。

      const router = new VueRouter({
        routes: [
          { 
      		path: '/search',
      	    component: SearchUser, 
      		props: (route) => ({ query: route.query.q }) 
      	}
        ]
      })
    
  • URL /search?q=vue 会将 {query: 'vue'} 作为属性传递给 SearchUser 组件。

posted @ 2018-03-14 17:04  不完美的完美  阅读(344)  评论(0编辑  收藏  举报