VUE router-view 頁面布局 (嵌套路由+命名視圖)


嵌套路由

實際生活中的應用界面,通常由多層嵌套的組件組合而成。同樣地,URL 中各段動態路徑也按某種結構對應嵌套的各層組件,例如:

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

借助 vue-router,使用嵌套路由配置,就可以很簡單地表達這種關系。

接着上節創建的 app:

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

這里的 <router-view> 是最頂層的出口,渲染最高級路由匹配到的組件。同樣地,一個被渲染組件同樣可以包含自己的嵌套 <router-view>。例如,在 User 組件的模板添加一個 <router-view>

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

要在嵌套的出口中渲染組件,需要在 VueRouter 的參數中使用 children 配置:

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

要注意,以 / 開頭的嵌套路徑會被當作根路徑。 這讓你充分的使用嵌套組件而無須設置嵌套的路徑。

你會發現,children 配置就是像 routes 配置一樣的路由配置數組,所以呢,你可以嵌套多層路由。

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

const router = new VueRouter({ routes: [ { path: '/user/:id', component: User,  children: [ // 當 /user/:id 匹配成功, // UserHome 會被渲染在 User 的 <router-view> 中 { path: '', component: UserHome }, // ...其他子路由 ] } ] })

命名視圖

有時候想同時 (同級) 展示多個視圖,而不是嵌套展示,例如創建一個布局,有 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 } } ] }) 

以上案例相關的可運行代碼請移步這里

#嵌套命名視圖

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

/settings/emails                                       /settings/profile
+-----------------------------------+                  +------------------------------+
| UserSettings                      |                  | UserSettings                 |
| +-----+-------------------------+ |                  | +-----+--------------------+ |
| | Nav | UserEmailsSubscriptions | |  +------------>  | | Nav | UserProfile        | |
| |     +-------------------------+ |                  | |     +--------------------+ |
| |     |                         | |                  | |     | UserProfilePreview | |
| +-----+-------------------------+ |                  | +-----+--------------------+ |
+-----------------------------------+                  +------------------------------+
  • Nav 只是一個常規組件。
  • UserSettings 是一個視圖組件。
  • UserEmailsSubscriptionsUserProfileUserProfilePreview 是嵌套的視圖組件。

注意:我們先忘記 HTML/CSS 具體的布局的樣子,只專注在用到的組件上

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

一個可以工作的示例的 demo 在這里

https://jsfiddle.net/22wgksa3/8174/
//**********************************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>Nested Named Views</h1>
<router-view></router-view>
</div>

//*****************************js*********************


const UserSettings = {
template: `
<div class="us">
<h2>User Settings start</h2>
<router-view ></router-view>
<router-view name="a"></router-view>
<router-view name="b"></router-view>
</br>
<h2>User Settings End</h2>
</div>
`
}

 

const Foo = { template: '<h2>pagecontent</h2>' }
const Bar = { template: '<h2>sidebar</h2>' }
const Baz = { template: '<h2>navbar</h2>' }

const router = new VueRouter({
mode: 'history',
routes: [
{ path: '/',
// You could also have named views at tho top
component: UserSettings,
children: [
{
path: '',
components: {
default: Baz,
a: Bar,
b: Foo
}
}
]
}
]
})

new Vue({
router,
el: '#app'
})

//****************************************效果如下********************* 

Nested Named Views

User Settings start

navbar

sidebar

pagecontent


User Settings End


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM