iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 11
2
自我挑戰組

新手初探 Vue系列 第 15

鐵人賽Day16 - Vue.js 基礎元件認識

Vue 裡面,我們可以使用元件來動態掛載 HTML
而元件到底是什麼? 如果以 HTML 來說的話,就會類似像是 Header Content 這樣一個區塊一個區塊
區塊裡面當然還可以包覆區塊,所以元件內也可以包覆元件

我在學習這部分的時候,其實還滿頭昏眼花的,但只要能搞清楚,相信對日後一定有益

接下來來個基本的 HTML 表格:

<div id="app">
  <table class="table">
    <thead>
    </thead>
    <tbody>
      <tr v-for="(item, key) in data" :key="key">
        <td>{{ item.name }}</td>
        <td>{{ item.cash }}</td>
        <td>{{ item.icash }}</td>
      </tr>
    </tbody>
  </table>
</div>

然後基本的 Vue 架構和資料:

<script>
var app = new Vue({
  el: '#app',
  data: {
    data: [
      {
        name: '小明',
        cash: 100,
        icash: 500,
      },
      {
        name: '杰倫',
        cash: 10000,
        icash: 5000,
      },
      {
        name: '漂亮阿姨',
        cash: 500,
        icash: 500,
      },
      {
        name: '老媽',
        cash: 10000,
        icash: 100,
      },
    ]
  }
});
</script>

接下來 <tbody> 下的 <tr> 是可以重複使用的,所以我們選擇這部分來改寫成元件
Vue 裡面要新增元件時,要在外面寫上 Vue.component('',{}); 裡面兩個參數,分別是自訂義的元件名字,和元件的物件內容:

<script>
Vue.component('row-component',{
    template: '#rowComponentTemplate'
});

var app = new Vue({
 ....
});
</script>

我們在 row-component 元件內有多一個 template 的屬性,這是用來等一下新增 x-template 與其 id 綁定的名字(可自訂義)
至於 x-template 是什麼? 簡單來說就是一個封裝我們的 HTML 模板的 <script>
所以這時候,我們再新增一個 <script>type 屬性需改成 text/x-template 且記得給予 id,而 id 就是剛剛 template 屬性自訂義的值,且把需要做成元件的 HTML 部分放在裡面:

<script type="text/x-template" id="rowComponentTemplate">
    <tr>
        <td>{{ item.name }}</td>
        <td>{{ item.cash }}</td>
        <td>{{ item.icash }}</td>
    </tr>
</script>

<script>
Vue.component('row-component',{
    template: '#rowComponentTemplate'
});

var app = new Vue({
 ....
});
</script>

這時候我們就可以把我們的元件用標籤的方式寫在 HTML 表格內:

<div id="app">
  <table class="table">
    <thead>
    </thead>
    <tbody>
      <row-component v-for="(item, key) in data" :key="key"></row-component>
    </tbody>
  </table>
</div>

會發現頁面上還是沒有資料顯示出來,這是因為每個元件的資料都是獨立的,所以 row-component 內的 item 是空的
這時候如果我們想要把資料傳遞給 row-component 接收,就要在剛剛新增元件的地方,新增一個 props 屬性:

<script>
Vue.component('row-component',{
    props: ['person'],
    template: '#rowComponentTemplate'
});

var app = new Vue({
 ....
});
</script>

props 屬性放的是一個陣列,這裡我們先自定義為 person,並動態把它綁在 row-component 上:

<div id="app">
  <table class="table">
    <thead>
    </thead>
    <tbody>
      <row-component v-for="(item, key) in data" :person="item" :key="key"></row-component>
    </tbody>
  </table>
</div>

並且 x-template 的地方,item 的部分也要改成 person:

<script type="text/x-template" id="rowComponentTemplate">
    <tr>
        <td>{{ person.name }}</td>
        <td>{{ person.cash }}</td>
        <td>{{ person.icash }}</td>
    </tr>
</script>

會發現資料呈現上去了,可是會有跑版的情況,這是 <table> 的特性,在 <tbody> 後面都是接 <tr> 而我們卻接了我們新建的元件,如果這時候檢查元件(F12),會發現 HTML 結構會如下:

<div id="app">
    <tr></tr>
    <tr></tr>
    <tr></tr>
    <tr></tr>
    <table>
    </table>
</div>

這跟我們原先預期的情況不一樣,因為我們要把 <tr> 掛在 <table> 內的 <tbody>
這時候我們可以把 HTML 的部分改成如下:

<div id="app">
  <table class="table">
    <thead>
    </thead>
    <tbody>
      <tr is="row-component" v-for="(item, key) in data" :person="item" :key="key"></tr>
    </tbody>
  </table>
</div>

會發現新增了一個 is 屬性,值就是我們新增的元件,這時候跑版問題就會解決了
元件這裡可以多看,個人覺得稍複雜,或者可以多找一點文獻來看


上一篇
鐵人賽Day14 - Computed & Watch
下一篇
鐵人賽Day17 - Vue.js 基礎元件認識 -2
系列文
新手初探 Vue30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
清心明月
iT邦新手 3 級 ‧ 2020-04-24 04:53:31

謝謝, 真的弄到頭大

<div id="app">
    <tr></tr>
    <tr></tr>
    <tr></tr>
    <tr></tr>
    <table>
    </table>
</div>
<tr is="row-component" v-for="(item, key) in data" :person="item" :key="key"></tr>

我要留言

立即登入留言