1. 程式人生 > >VueJs(11)---vue-router(進階2)

VueJs(11)---vue-router(進階2)

www. HR 布局 ren profile tps 使用 可能 title

vue-router(進階2)

上篇文章講了第一篇vue-router相關文章,文章地址:VueJs(10)---vue-router(進階1)

一、命名路由

有時候,通過一個名稱來標識一個路由顯得更方便一些,特別是在鏈接一個路由,或者是執行一些跳轉的時候。你可以在創建 Router 實例的時候,在 routes 配置中給某個路由設置名稱。我個人理解就相當於給路徑取個名字,調用的時候,這個名字就指這個路徑,不然有些路徑很長,直接寫太麻煩。

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

要鏈接到一個命名路由,可以給 router-linkto 屬性傳一個對象:

<router-link :to="{ name: ‘user‘, params: { userId: 123 }}">User</router-link>

這跟代碼調用 router.push() 是一回事:

router.push({ name: ‘user‘, params: { userId: 123 }})

這兩種方式都會把路由導航到 /user/123 路徑。

二、命名視圖

1、命名視圖

命名視圖只需兩步:第一在router-view添加name屬性第二在路由中用components。

有時候想同時(同級)展示多個視圖,而不是嵌套展示,例如創建一個布局,有 sidebar(側導航) 和 main(主內容) 兩個視圖,這個時候命名視圖就派上用場了。你可以在界面中擁有多個單獨命名的視圖,而不是只有一個單獨的出口。如果 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
      }
    }
  ]
})

舉例

<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>Named Views</h1>
    <ul>
        <li>
            <router-link to="/">/</router-link>
        </li>
        <li>
            <router-link to="/other">/other</router-link>
        </li>
    </ul>
    <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>
</div>
<script>
    const Foo = {
        template: <div>foo</div>
    }
    const Bar = {
        template: <div>bar</div>
    }
    const Baz = {
        template: <div>baz</div>
    }

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

    new Vue({
        router,
        el: #app
    })
</script>

效果

2、嵌套命名視圖

我們也有可能使用命名視圖創建嵌套視圖的復雜布局。這時你也需要命名用到的嵌套 router-view 組件。我們以一個設置面板為例:

技術分享圖片

  • Nav 只是一個常規組件。
  • UserSettings 是一個視圖組件。
  • UserEmailsSubscriptionsUserProfileUserProfilePreview 是嵌套的視圖組件。

UserSettings 組件的 <template> 部分應該是類似下面的這段代碼:

<!-- UserSettings.vue -->
<div>
  <h1>User Settings</h1>
  <NavBar/>
  <router-view/>
  <router-view name="helper"/>
</div>

然後你可以用這個路由配置完成該布局:

{
  path: ‘/settings‘,
  // 你也可以在頂級路由就配置命名視圖
  component: UserSettings,
  children: [{
    path: ‘emails‘,
    component: UserEmailsSubscriptions
  }, {
    path: ‘profile‘,
    components: {
      default: UserProfile,
      helper: UserProfilePreview
    }
  }]
}

三、重定向和別名

1、重定向

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

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

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

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

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

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

註意導航守衛並沒有應用在跳轉路由上,而僅僅應用在其目標上。在下面這個例子中,為 /a 路由添加一個 beforeEach beforeLeave 守衛並不會有任何效果。

2、別名

重定向和別名的區別

重定向:當用戶訪問 /a時,URL 將會被替換成 /b,然後匹配路由為 /b,那麽『別名』又是什麽呢?

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

上面對應的路由配置為:

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

『別名』的功能讓你可以自由地將 UI 結構映射到任意的 URL,而不是受限於配置的嵌套路由結構。

四、路由組件傳參

路由組件傳參一樣需要:props,屬性,通過props我們不用在組件中用{{ $route.params.id }}獲取屬性值,而可以直接把route.params 設置為組件屬性。

使用 props 將組件和路由解耦:

(1) 不用props

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

(2)通過 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 被設置為 trueroute.params 將會被設置為組件屬性。

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

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

(4)函數模式

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

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

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

請盡可能保持 props 函數為無狀態的,因為它只會在路由發生變化時起作用。如果你需要狀態來定義 props,請使用包裝組件,這樣 Vue 才可以對狀態變化做出反應。

五、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 依賴的頁面。

想太多,做太少,中間的落差就是煩惱。想沒有煩惱,要麽別想,要麽多做。中尉【20】

VueJs(11)---vue-router(進階2)