1. 程式人生 > >路由vue-router基礎

路由vue-router基礎

不同 lan 種類型 tor home api 客戶端 rip 模塊化

官方文檔

1. 基本例子

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>

js

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

// 現在,應用已經啟動了!

2. 動態路由匹配

  1. 定義routes時候

    routes: [
    // 動態路徑參數 以冒號開頭
    { path: '/user/:id', component: User }
    ]
  2. 獲取參數方法

    this.$route.params

  3. 可以設置多個參數
    ```
    //格式:
    /user/:username/post/:post_id

//使用
/user/evan/post/123

//this.$route.params結果:
{ username: ‘evan‘, post_id: 123 }


4. 路由參數變化

提醒一下,當使用路由參數時,例如從 /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. 匹配優先級 

有時候,同一個路徑可以匹配多個路由,此時,匹配的優先級就按照路由的定義順序:誰先定義的,誰的優先級就最高。

6. 高級匹配模式

vue-router 使用 path-to-regexp 作為路徑匹配引擎,所以支持很多高級的匹配模式,[文檔](https://github.com/pillarjs/path-to-regexp#parameters)

# 3. 嵌套路由

1. 頂層出口例子

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

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


2. 嵌套出口例子

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

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
}
]
}
]
})


3. 空的子路由

當你訪問 /user/foo 時,User 的出口是不會渲染任何東西,這是因為沒有匹配到合適的子路由。如果你想要渲染點什麽,可以提供一個 空的 子路由:

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

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

]
})


# 4. 編程式導航

實現跳轉兩種方式

- 使用<router-link>

Go to Foo
User


- 編寫代碼(route.push(),route.replace(),router.go())

完整模式

router.push(location, onComplete?, onAbort?)
router.replace(location, onComplete?, onAbort?)
router.go(n)


1. router.push

router.push 方法向 history 棧添加一個新的記錄,所以,當用戶點擊瀏覽器後退按鈕時,則回到之前的 URL。

/ 字符串
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

**同樣的規則也適用於 router-link 組件的 to 屬性。**

2. router.replace
router.replace跟 router.push 很像,唯一的不同就是,它不會向 history 添加新記錄,而是跟它的方法名一樣 —— 替換掉當前的 history 記錄。

3. router.go

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)


4. 參數

在 2.2.0+,可選的在 router.push 或 router.replace 中提供 onComplete 和 onAbort 回調作為第二個和第三個參數。這些回調將會在導航成功完成 (在所有的異步鉤子被解析之後) 或終止 (導航到相同的路由、或在當前導航完成之前導航到另一個不同的路由) 的時候進行相應的調用。

註意:如果目的地和當前路由相同,只有參數發生了改變 (比如從一個用戶資料到另一個 /users/1 -> /users/2),你需要使用 beforeRouteUpdate 來響應這個變化 (比如抓取用戶信息)

# 5. 命名路由

有時候,通過一個名稱來標識一個路由顯得更方便一些,特別是在鏈接一個路由,或者是執行一些跳轉的時候。你可以在創建 Router 實例的時候,在 routes 配置中給某個路由設置名稱。

const router = new VueRouter({
routes: [
{
path: ‘/user/:userId‘,
name: ‘user‘,
component: User
}
]
})


# 6. 命名視圖

有時候想同時(同級)展示多個視圖,而不是嵌套展示,例如創建一個布局,有 sidebar(側導航) 和 main(主內容) 兩個視圖,這個時候命名視圖就派上用場了。你可以在界面中擁有多個單獨命名的視圖,而不是只有一個單獨的出口。如果 router-view 沒有設置名字,那麽默認為 default。



一個視圖使用一個組件渲染,因此對於同個路由,多個視圖就需要多個組件。確保正確使用 components 配置(帶上 s):

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


# 7. 重定向和別名

1. 重定向

重定向也是通過 routes 配置來完成,下面例子是從 /a 重定向到 /b:

const router = new VueRouter({
routes: [
{ path: ‘/a‘, redirect: ‘/b‘ }
]
})


重定向的目標也可以是一個命名的路由:

const router = new VueRouter({
routes: [
{ path: ‘/a‘, redirect: { name: ‘foo‘ }}
]
})


甚至是一個方法,動態返回重定向目標:

const router = new VueRouter({
routes: [
{ path: ‘/a‘, redirect: to => {
// 方法接收 目標路由 作為參數
// return 重定向的 字符串路徑/路徑對象
}}
]
})


更多實例

routes: [
{ path: ‘/‘, component: Home,
children: [
{ path: ‘‘, component: Default },
{ path: ‘foo‘, component: Foo },
{ path: ‘bar‘, component: Bar },
{ path: ‘baz‘, name: ‘baz‘, component: Baz },
{ path: ‘with-params/:id‘, component: WithParams },
// relative redirect to a sibling route
{ path: ‘relative-redirect‘, redirect: ‘foo‘ }
]
},

// absolute redirect
{ path: '/absolute-redirect', redirect: '/bar' },

// dynamic redirect, note that the target route `to` is available for the redirect function
{ path: '/dynamic-redirect/:id?',
  redirect: to => {
    const { hash, params, query } = to
    if (query.to === 'foo') {
      return { path: '/foo', query: null }
    }
    if (hash === '#baz') {
      return { name: 'baz', hash: '' }
    }
    if (params.id) {
      return '/with-params/:id'
    } else {
      return '/bar'
    }
  }
},

// named redirect
{ path: '/named-redirect', redirect: { name: 'baz' }},

// redirect with params
{ path: '/redirect-with-params/:id', redirect: '/with-params/:id' },

// catch all redirect
{ path: '*', redirect: '/' }

]
```

  1. 別名

『重定向』的意思是,當用戶訪問 /a時,URL 將會被替換成 /b,然後匹配路由為 /b。

別名: /a 的別名是 /b,意味著,當用戶訪問 /b 時,URL 會保持為 /b,但是路由匹配則為 /a,就像用戶訪問 /a 一樣。

上面對應的路由配置為:

const router = new VueRouter({
  routes: [
    { path: '/a', component: A, alias: '/b' }
  ]
})

更多例子

routes: [
    { path: '/home', component: Home,
      children: [
        // absolute alias
        { path: 'foo', component: Foo, alias: '/foo' },
        // relative alias (alias to /home/bar-alias)
        { path: 'bar', component: Bar, alias: 'bar-alias' },
        // multiple aliases
        { path: 'baz', component: Baz, alias: ['/baz', 'baz-alias'] }
      ]
    }
]

8. 向路由組件傳遞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 }
    }
  ]
})
  1. 布爾模式

如果props被設置為true,route.params將會被設置為組件屬性。

  1. 對象模式

如果props是一個對象,它會被按原樣設置為組件屬性。當props是靜態的時候有用。

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

你可以創建一個函數返回props。這樣你便可以將參數轉換成另一種類型,將靜態值與基於路由的值結合等等。

const router = new VueRouter({
  routes: [
    { path: '/search', component: SearchUser, props: (route) => ({ query: route.query.q }) }
  ]
})

Url: /search?q=vue 會將 {query: "vue"} 作為屬性傳遞給SearchUser組件。

9. HTML5 History模式

vue-router 默認 hash 模式 —— 使用 URL 的 hash 來模擬一個完整的 URL,於是當 URL 改變時,頁面不會重新加載。

如果不想要很醜的 hash,我們可以用路由的 history 模式,這種模式充分利用 history.pushState API 來完成 URL 跳轉而無須重新加載頁面。

const router = new VueRouter({
  mode: 'history',
  routes: [...]
})

當你使用 history 模式時,URL 就像正常的 url,例如 http://yoursite.com/user/id,也好看!

不過這種模式要玩好,還需要後臺配置支持。因為我們的應用是個單頁客戶端應用,如果後臺沒有正確的配置,當用戶在瀏覽器直接訪問 http://oursite.com/user/id 就會返回 404,這就不好看了。

所以呢,你要在服務端增加一個覆蓋所有情況的候選資源:如果 URL 匹配不到任何靜態資源,則應該返回同一個 index.html 頁面,這個頁面就是你 app 依賴的頁面。

給個警告,因為這麽做以後,你的服務器就不再返回 404 錯誤頁面,因為對於所有路徑都會返回 index.html 文件。為了避免這種情況,你應該在 Vue 應用裏面覆蓋所有的路由情況,然後在給出一個 404 頁面。

const router = new VueRouter({
  mode: 'history',
  routes: [
    { path: '*', component: NotFoundComponent }
  ]
})

路由vue-router基礎