上篇文章講了第一篇vue-router相關文章,文章地址:VueJs(10)---vue-router(進階1)html
有時候,經過一個名稱來標識一個路由顯得更方便一些,特別是在連接一個路由,或者是執行一些跳轉的時候。你能夠在建立 Router 實例的時候,在 routes
配置中給某個路由設置名稱。我我的理解就至關於給路徑取個名字,調用的時候,這個名字就指這個路徑,否則有些路徑很長,直接寫太麻煩。vue
const router = new VueRouter({ routes: [ { path: '/user/:userId', name: 'user', component: User } ] })
要連接到一個命名路由,能夠給 router-link
的 to
屬性傳一個對象:vue-router
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
這跟代碼調用 router.push()
是一回事:瀏覽器
router.push({ name: 'user', params: { userId: 123 }})
這兩種方式都會把路由導航到 /user/123
路徑。app
命名視圖只需兩步:第一在router-view添加name屬性,第二在路由中用components。
ide
有時候想同時(同級)展現多個視圖,而不是嵌套展現,例如建立一個佈局,有 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
}
}
]
})
舉例post
<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>
效果:測試
咱們也有可能使用命名視圖建立嵌套視圖的複雜佈局。這時你也須要命名用到的嵌套 router-view
組件。咱們以一個設置面板爲例:
Nav
只是一個常規組件。UserSettings
是一個視圖組件。UserEmailsSubscriptions
、UserProfile
、UserProfilePreview
是嵌套的視圖組件。 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)重定向也是經過 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
守衛並不會有任何效果。
重定向和別名的區別:
重定向:當用戶訪問 /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
被設置爲 true
,route.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 才能夠對狀態變化作出反應。
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】