將HTML網頁Vue元件化
前一篇簡單的介紹了
元件的基本常識 。這篇我們要來試試看,實際上如何做出元件化的網頁。
第一個例子,我們要透過bootstrap網站上面的html範例,逐步將它改成Vue元件的頁面。
今天我們要練習的畫面,大家可以在這裡取得,下載為html檔案。下載html的方法這裡就不贅述。
https://getbootstrap.com/docs/4.1/examples/
分析頁面
首先,我們先分析一下這個bootstrap的html範例
有頁首、頁尾、且中間主畫面可以分成兩個區塊。
下面區塊可以再分成更細的區塊,總共有六個區塊構成。
我們可以把分析的結果畫成下面的圖表。
網頁可以分割成Header、Footer、主要內容三段。主要內容的部分可以分上下,上面是bigBoard下面是一個個Item組成,總共有六個Item。
再回來對應下載的html原始碼。我們發現:
Header 區塊,從
<header>
開始到
</header>
結束。
Footer 區塊,從
<footer class="text-muted">
開始到
</footer>
結束。
主要內容區塊,從
<main role="main">
開始到
</main>
結束。
主要內容區塊,又可以分成兩段,上半段從
<section class="jumbotron text-center">
開始,到
</section>
結束; 下半段從
<div class="album py-5 bg-light">
開始,到
</div>
結束,裡面有六個Item,每個Item都從。
<div class="col-md-4">
開始,到
</div>
結束。
建立Vue
依照上面的分割方式,我們可以將整個網站分成幾個Vue元件。在分割之前,我們先在頁面上安裝Vue.js。一樣,我們先插入下面兩個部分。
Vue.js的CDN檔案連結
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
建立一個Vue 實例,連結Html上的<div id="app"> </div>
<script>
var app = new Vue({
el: "#app",
})
</script>
當這一切都設定好之後,我們就要來註冊Vue元件了。
依照上面的分析,我們需要建立Head 、Footer、bigBoard、cardCom等元件。
Head 、Footer元件
先從Head 開始,註冊全域元件pageHeader,樣板採用x-template方式,名稱為#header。
Vue.component('pageHeader', {
template: "#header",
data: function () {
return {
title: "ABC",
about: "關於這個網站",
contact: "聯絡我們"
}
}
});
因此,先建立一個x-template 的 script,並且賦予一個header的id。
<script type="text/x-template" id="header">
//樣板
</script>
接著將,Header 區塊(從
<header>
開始到
</header>
結束)貼近去。結果如下:
<script type="text/x-template" id="header">
<header>
<div class="collapse bg-dark" id="navbarHeader">
<div class="container">
<div class="row">
<div class="col-sm-8 col-md-7 py-4">
<h4 class="text-white">{{about}}</h4>
<p class="text-muted">Add some information about the album below, the author, or any other
background context. Make it a few sentences long so folks can pick up some informative
tidbits.
Then, link them off to some social networking sites or contact information.</p>
</div>
<div class="col-sm-4 offset-md-1 py-4">
<h4 class="text-white">{{contact}}</h4>
<ul class="list-unstyled">
<li><a href="#" class="text-white">Follow on Twitter</a></li>
<li><a href="#" class="text-white">Like on Facebook</a></li>
<li><a href="#" class="text-white">Email me</a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="navbar navbar-dark bg-dark shadow-sm">
<div class="container d-flex justify-content-between">
<a href="#" class="navbar-brand d-flex align-items-center">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" stroke="currentColor"
stroke-linecap="round" stroke-linejoin="round" stroke-width="2" aria-hidden="true" class="mr-2"
viewBox="0 0 24 24" focusable="false">
<path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z" />
<circle cx="12" cy="13" r="4" /></svg>
<strong>{{title}}</strong>
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarHeader"
aria-controls="navbarHeader" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
</div>
</div>
</header>
</script>
最後,在Html上的
<div id="app"> </div>
中間,放入
<page-header></page-header>
注意,雖然元件命名為pageHeader(有大小寫),由於在Html中無法分辨大小寫,於是呼叫元件時必須採用<page-header>的方式,也就是 page與header需要小寫,且兩者中間需要一個橫槓(-)才行。
接著,就可以測試看看header是否正常出現在頁面上。
如果沒問題的話,接著就用同樣的方式製作Footer的部分。
註冊Vue元件pageFooter。
Vue.component('pageFooter', {
template: "#footer"
})
建立一個x-template,並且貼上樣板。
<script type="text/x-template" id="footer">
<footer class="text-muted">
<div class="container">
<p class="float-right">
<a href="#">Back to top</a>
</p>
<p>Album example is © Bootstrap, but please download and customize it for yourself!</p>
<p>New to Bootstrap? <a href="https://getbootstrap.com/">Visit the homepage</a> or read our <a href="/docs/4.3/getting-started/introduction/">getting
started guide</a>.</p>
</div>
</footer>
</script>
在Html上的呼叫pageFooter元件。
<page-footer></page-footer>
中間區塊元件
前面Header、Footer部分已經改成Vue元件,我們可以看一下目前的頁面的結構。
<div id="app">
<page-header></page-header>
<!--component pageMain -->
<main role="main">
<!-- component jumbo --><!-- //component jumbo -->
<!-- component container --><!-- //component container -->
</main>
<!--// component pageMain -->
<page-footer></page-footer>
</div>
<main role="main"></main>
中間的部分,我們分兩部分,上半部要放在
<!-- component jumbo --><!-- //component jumbo -->
裡面,下半部則需要放在
<!-- component container --><!-- //component container -->
中間。
上半部跟前面的Header、Footer區塊一樣,先註冊Vue元件jumboCom。
Vue.component('jumboCom', {
template: "#jumbo"
})
接著建立一個x-template,並且貼上樣板。
<script type="text/x-template" id="jumbo">
<section class="jumbotron text-center">
<div class="container">
<h1 class="jumbotron-heading">Album example</h1>
<p class="lead text-muted">Something short and leading about the collection below—its contents, the
creator, etc. Make it short and sweet, but not too short so folks don’t simply skip over it
entirely.</p>
<p>
<a href="#" class="btn btn-primary my-2">Main call to action</a>
<a href="#" class="btn btn-secondary my-2">Secondary action</a>
</p>
</div>
</section>
</script>
最後,在Html上的呼叫jumboCom元件。
<div id="app">
<page-header></page-header>
<!--component pageMain -->
<main role="main">
<!-- component jumbo -->
<jumbo-com></jumbo-com>
<!-- // component jumbo -->
<!-- component container --><!-- //component container -->
</main>
<!--// component pageMain -->
<page-footer></page-footer>
</div>
到這裡為止,剩下最後的一塊,整個畫面就跟Bootstrap上面取得的畫面一樣了。
下半部區塊,需要放在
<!-- component container --><!-- //component container -->
中間。比較單純的做法是,直接在中間放入item的元件。
<!-- component container -->
<div class="album py-5 bg-light">
<div class="container">
<div class="row">
//item元件
</div>
</div>
</div>
<!-- // component container -->
先依照上面說明的方式,先註冊Vue元件cardCom,並建立一個x-template,並且貼上樣板。
Vue.component('cardCom', {
template: "#cardcom",
});
<script type="text/x-template" id="cardcom">
<div class="col-md-4">
<div class="card mb-4 shadow-sm">
<img width="100%" height="225" src="photo.img">
<div class="card-body">
<p class="card-text">文字</p>
<div class="d-flex justify-content-between align-items-center">
<div class="btn-group">
<button type="button" class="btn btn-sm btn-outline-secondary">View</button>
<button type="button" class="btn btn-sm btn-outline-secondary">Edit</button>
</div>
<small class="text-muted">9 mins</small>
</div>
</div>
</div>
</div>
</script>
在Html上的呼叫cardCom元件。
<!-- component container -->
<div class="album py-5 bg-light">
<div class="container">
<div class="row">
<card-com></card-com>
</div>
</div>
</div>
<!-- // component container -->
Item依照數量自動產生
到目前為止,方法都跟上面一樣,你會看到中間下面區會出現一個item。接下來,要讓 item依照資料的數量自動增加,目標是六個item。
先在Vue實體加上data選項,在postsdata 中建立一筆資料。
<script>
var app = new Vue({
el: "#app",
data() {
return {
postsdata: [{
img: "好",
url: "info-center.jpg",
context: ` Lorem ipsum dolor sit amet consectetur adipisicing elit. Magnam aliquam alias vero quas id
voluptates assumenda illum culpa. Soluta repudiandae nemo consequatur facere quibusdam placeat sapiente
reprehenderit quod hic in!`
}]
}
}
})
</script>
在cardCom元件中,加入props。(props在下一篇會說明)
Vue.component('cardCom', {
template: "#cardcom",
props: ["posts"],
});
將原來的
<card-com></card-com>
部分,改成下面的程式碼:
<card-com v-for="(item, key) in postsdata" :key="key" :posts="item"></card-com>
其中,
:posts="item"
地方,綁定元件的資料從Vue實例的data函數中傳入。
而
v-for="(item, key) in postsdata"
的地方會依照data中postsdata內的資料的數量,一組一組顯示出來,目前只放了一組資料。
在x-template的部分也修改成下面程式碼。其中
{{posts.context}}
會將postsdata中的context顯示出來。
而在
<img width="100%" height="225" :src="posts.url" :alt="posts.img">
部分則使用v-bind的方式綁定src與alt兩個 img 的屬性。
<script type="text/x-template" id="cardcom">
<div class="col-md-4">
<div class="card mb-4 shadow-sm">
<img width="100%" height="225" :src="posts.url" :alt="posts.img">
<div class="card-body">
<p class="card-text">
{{posts.context}}
</p>
<div class="d-flex justify-content-between align-items-center">
<div class="btn-group">
<button type="button" class="btn btn-sm btn-outline-secondary">View</button>
<button type="button" class="btn btn-sm btn-outline-secondary">Edit</button>
</div>
<small class="text-muted">9 mins</small>
</div>
</div>
</div>
</div>
</script>
恭喜,第一筆資料已經出現在畫面上了。
接著,你可以再增加5筆資料,如此就大功告成了。
以下是原始碼
留言
張貼留言