Quasar 學習筆記 Ep 03 - Quasar 的 MainLayout 元件
Quasar 的 MainLayout 元件
當我們以 Quasar CLI 建立一個標準的 MPA 如下,這個網頁分成幾個部分,首先是左邊會有一個選單,這個選單的開關就在上方的 [三] 按鈕,上方藍色的部分是 Toolbar,顯示網站的名稱以及 Quasar 的版本。
- MainLayout 元件
- 使用 Layout Biulder
- 將 Home / About / News 加入 Drawer (Mobile App Style)
- 將 Home / About / News 加入 Tab (Web Style)
MainLayout 元件
首先我們看一下 MainLayout.vue 裡面的 <template> 段。<template>
<q-layout view="lHh Lpr lFf">
<q-header elevated>
<q-toolbar>
<q-btn
flat
dense
round
icon="menu"
aria-label="Menu"
@click="toggleLeftDrawer"
/>
<q-toolbar-title>
Quasar App
</q-toolbar-title>
<div>Quasar v{{ $q.version }}</div>
</q-toolbar>
</q-header>
<q-drawer
v-model="leftDrawerOpen"
show-if-above
bordered
>
<q-list>
<q-item-label
header
>
Essential Links
</q-item-label>
<EssentialLink
v-for="link in essentialLinks"
:key="link.title"
v-bind="link"
/>
</q-list>
</q-drawer>
<q-page-container>
<router-view />
</q-page-container>
</q-layout>
</template>
為了方便解釋,我們先看網頁所呈現的樣貌是如何在 MainLayout 裡面定義的,整個網頁內容是包在 <template></template> 中,<q-layout> </q-layout> 定義網頁的樣貌,包含三個部分,上方藍色的 Header,左邊的 Drawer,以及中間的 Page。
<template>
<q-layout>
<q-header>
<q-toolbar>
<q-btn/>
<q-toolbar-title> XXX </q-toolbar-title>
</q-toolbar>
</q-header>
<q-drawer>
<q-list>
<q-item-label> XXX </q-item-label>
</q-list>
</q-drawer>
<q-page-container>
<router-view />
</q-page-container>
</q-layout>
</template>
Header 定義在 <q-header> </q-header> 中,裡面放了一個 Toolbar,<q-toolbar> </q-toolbar>裡面又放了兩樣東西,分別是 <q-btn/> 按鈕用來控制左邊的 Drawer 開合,<q-toolbar-title> 則顯示標題文字。
Drawer 選單裡面的選項,則是定義在 <q-list> </q-list> 裡面,實際渲染方式我們後面再談。
最後是網頁(Page),定義在 <q-page-container> 中,實際渲染的內容則是由 Router 控制,故只需要加入 <router-view/>。
Layout Builder
Quasar 的 Layout 可以利用 Layout Builder 來製作,可以省去寫程式的時間,請在瀏覽器輸入網址:https://quasar.dev/layout-builder,即可進入。
第一步,我們可以選取這五個項目,來決定網頁基本的格局。如果要重現 helloquasar 的網頁 Layout,請取消 QFooter,Right-Side QDrawer,以及Navigation Bar。
- 四邊 上(h / H)下(f / F)左(l / L)右(r / R):大寫代表 Page 捲動時,固定在網頁上不動;小寫代表跟著捲動。
- 四角 左上(l / h) 右上(r / h) 左下(l / f) 右下(r / f):選擇哪個要在上面。
完成之後,按下 Export Layout 就會產生程式碼,我們複製之後貼在 MainLayout.vue 裡面即可。其中 <q-layout view="lHh Lpr lFf"> 就是九宮格裡面上中下三個字串。
Drawer 的選項內容
<q-list>
<q-item-label
header
>
Essential Links
</q-item-label>
<EssentialLink
v-for="link in essentialLinks"
:key="link.title"
v-bind="link"
/>
</q-list>
裡面只有一個 Quasar 標籤命令,就是 <q-list>,裡面定義了 Label 跟內容,所有的內容,都是由 EssentialLink 元件來處理,傳入元件的參數,使用了 v-for="link in essentialLinks" ,所以我們要來找一下 essentialLinks 這個陣列,它放在 <script> 中:
<script>
import EssentialLink from 'components/EssentialLink.vue'
const linksList = [
{
title: 'Docs',
caption: 'quasar.dev',
icon: 'school',
link: 'https://quasar.dev'
},
{
title: 'Github',
caption: 'github.com/quasarframework',
icon: 'code',
link: 'https://github.com/quasarframework'
},
{
title: 'Discord Chat Channel',
caption: 'chat.quasar.dev',
icon: 'chat',
link: 'https://chat.quasar.dev'
},
{
title: 'Forum',
caption: 'forum.quasar.dev',
icon: 'record_voice_over',
link: 'https://forum.quasar.dev'
},
{
title: 'Twitter',
caption: '@quasarframework',
icon: 'rss_feed',
link: 'https://twitter.quasar.dev'
},
{
title: 'Facebook',
caption: '@QuasarFramework',
icon: 'public',
link: 'https://facebook.quasar.dev'
},
{
title: 'Quasar Awesome',
caption: 'Community Quasar projects',
icon: 'favorite',
link: 'https://awesome.quasar.dev'
}
];
import { defineComponent, ref } from 'vue'
export default defineComponent({
name: 'MainLayout',
components: {
EssentialLink
},
setup () {
const leftDrawerOpen = ref(false)
return {
essentialLinks: linksList,
leftDrawerOpen,
toggleLeftDrawer () {
leftDrawerOpen.value = !leftDrawerOpen.value
}
}
}
})
</script>
這裡使用了 Vue Composition API 的程式寫法,以 setup() 包裝了資料跟方法,我們先不深究,不過馬上就可以看到 essentialLinks: linksList ,所以馬上在看 linksList 的內容,在 <script> 上面,每一個 item 都依照下面的方式來定義。
{
title: 'Docs',
caption: 'quasar.dev',
icon: 'school',
link: 'https://quasar.dev'
},
當這個陣列以 v-for 傳入 EssentialLink 元件之後,所有 items 就會一一渲染出來。
EssentialLink.vue
<template>
<q-item
clickable
tag="a"
target="_blank"
:href="link"
>
<q-item-section
v-if="icon"
avatar
>
<q-icon :name="icon" />
</q-item-section>
<q-item-section>
<q-item-label>{{ title }}</q-item-label>
<q-item-label caption>
{{ caption }}
</q-item-label>
</q-item-section>
</q-item>
</template>
<script>
import { defineComponent } from 'vue'
export default defineComponent({
name: 'EssentialLink',
props: {
title: {
type: String,
required: true
},
caption: {
type: String,
default: ''
},
link: {
type: String,
default: '#'
},
icon: {
type: String,
default: ''
}
}
})
</script>
將 Home / About / News 網頁放入 Drawer 選單
原本範例程式中的選單,都是一些連結,點選時就會開啟一個新的網頁,然後連結到另一個 Quasar 相關的網站。現在我們就來實作將 Home/About/News放在前三個選項裡面。
先確定你已經依照 Ep 02 的步驟,對程式做了修改,並且可以用 http://localhost:8080/about 以及 http://localhost:8080/news 能夠看見網頁內容,接著我們就來修改 MainLayout.vue。
const linksList = [
{
title: '首頁',
caption: '本網站的首頁',
icon: 'school',
link: ''
},
{
title: '關於',
caption: '關於本網站的說明',
icon: 'code',
link: 'about'
},
{
title: '最新消息',
caption: '宣布本網站的最新動態',
icon: 'chat',
link: 'news'
},
然後我希望點選之後,能夠在原本的網頁裡面顯示,而不要新開一個網頁,所以再開啟 EssentialLink.vue,將 target="_blank" 改為 target="_self"。
<template>
<q-item
clickable
tag="a"
target="_self"
:href="link"
>
執行結果。
{
title: '首頁',
caption: '本網站的首頁',
icon: 'home',
link: ''
},
{
title: '關於',
caption: '關於本網站的說明',
icon: 'lightbulb',
link: 'about'
},
{
title: '最新消息',
caption: '宣布本網站的最新動態',
icon: 'newspaper',
link: 'news'
},
App Style vs. Web Style
目前 helloquasar 的執行結果,其實比較像是手機App 的風格,如果手機跟電腦是連接通一個無線網域,我們就可以在手機裡面看到執行結果:
而過去在網頁上的風格通常子網頁的按鈕會在 Header 上面。
<q-tabs align="left">
<q-route-tab to="/page1" label="Page One" />
<q-route-tab to="/page2" label="Page Two" />
<q-route-tab to="/page3" label="Page Three" />
</q-tabs>
加入到 MainLayout.vue 的 </q-toolbar> 與 </q-header> 之間,並調整程式碼,如下圖:
<q-header elevated>
<q-toolbar>
<q-btn
flat
dense
round
icon="menu"
aria-label="Menu"
@click="toggleLeftDrawer"
/>
<q-toolbar-title>
Quasar App
</q-toolbar-title>
<div>Quasar v{{ $q.version }}</div>
</q-toolbar>
<!-- 加在這裡 -->
<q-tabs align="left">
<q-route-tab to="/" label="首頁" />
<q-route-tab to="/about" label="關於本站" />
<q-route-tab to="/news" label="最新消息" />
</q-tabs>
</q-header>
執行結果如下:
<template>
<q-layout view="lHh Lpr lFf">
<q-header elevated>
<q-toolbar>
<q-btn
flat
dense
round
icon="menu"
aria-label="Menu"
@click="toggleLeftDrawer"
/>
<q-toolbar-title>
Quasar App
</q-toolbar-title>
<div>Quasar v{{ $q.version }}</div>
</q-toolbar>
</q-header>
<q-drawer
v-model="leftDrawerOpen"
show-if-above
bordered
>
<q-list>
<q-item-label
header
>
Essential Links
</q-item-label>
<EssentialLink
v-for="link in essentialLinks"
:key="link.title"
v-bind="link"
/>
</q-list>
</q-drawer>
<q-page-container>
<router-view />
</q-page-container>
<q-footer>
<q-tabs align="left">
<q-route-tab to="/" label="首頁" />
<q-route-tab to="/about" label="關於本站" />
<q-route-tab to="/news" label="最新消息" />
</q-tabs>
</q-footer>
</q-layout>
</template>
手機展示結果:
各位覺得呢?
留言
張貼留言