iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 11
0
自我挑戰組

新手初探 Vue系列 第 12

鐵人賽Day12 - v-for 使用細節

在前面我們有稍微提到了 v-for,現在來複習一下,一樣先建構 Vue 的基本結構和資料:

<script>
var app = new Vue({
  el: '#app',
  data: {
    arrayData: [
      {
        name: '小明',
        age: 16
      },
      {
        name: '漂亮阿姨',
        age: 24
      },
      {
        name: '杰倫',
        age: 20
      }
    ],
    objectData: {
      ming: {
        name: '小明',
        age: 16
      },
      auntie: {
        name: '漂亮阿姨',
        age: 24
      },
      jay: {
        name: '杰倫',
        age: 20
      }
    },
    filterArray: [],
    filterText: ''
  },
  methods: {
      reverseArray: function(){
          this.arrayData.reverse();
      },
      filterData: function(){
          var vm = this;
          vm.filterArray = vm.arrayData.filter(function(item){
              return item.name.match(vm.filterText);
          });
      },
      cantWork: function(){
          //this.arrayData.length = 0;
          //this.arrayData[0] = {
          //    name: '小強',
          //    age: 99
          //}
          Vue.set(this.arrayData, 0,{
            name: '小強',
            age: 99
          })
      }
  }
});
</script>

先來複習一下基本使用 v-for 的方法:

<ul>
    <li v-for="(item, key) in arrayData">
      {{ key }} - {{ item.name }} {{ item.age }} 歲
    </li>
</ul>

這樣就會把 arrayData 內的每筆資料撈出來

接著如果我們的資料是帶有 input 元素時,就會產生一些問題,假設我們是要反轉陣列,先在 button 元素內新增點擊會反轉陣列的 function,我把這個 function 補在最上面的 script

  <ul>
    <li v-for="(item, key) in arrayData">
      {{ key }} - {{ item.name }} {{ item.age }} 歲 <input type="text">
    </li>
  </ul>
  <button class="btn btn-outline-primary" @click="reverseArray">反轉陣列</button>

這時候如果我們可以在 input 內輸入一點東西,會發現 input 內的資料並沒有辦法做反轉,僅只有 arrayData 的資料在做反轉,這部分會在後續做補充,Vue 的官方網站也有講解到,這時候我們要增加 key 屬性來讓 Vue 重新做渲染
這裡就先用 item.age 來做 key 屬性的值

  <ul>
    <li v-for="(item, key) in arrayData" :key="item.age">
      {{ key }} - {{ item.name }} {{ item.age }} 歲 <input type="text">
    </li>
  </ul>
  <button class="btn btn-outline-primary" @click="reverseArray">反轉陣列</button>

這時候 input 元素也會跟著做反轉了

假設我們現在要在 v-for 做過濾資料,要在欄位內輸入資料的名字,並把那筆資料撈出來:
分別先把定義好的資料 filterTextfilterArray 綁上去 input 元素和 v-for
並在 input 元素內按下 Enter 鍵時,執行 filterData 這個 function
內容一樣補在最上方的 script

  <input type="text" class="form-control" v-model="filterText" @keyup.enter="filterData">
  <ul>
    <li v-for="(item, key) in filterArray" :key="item.age">
      {{ key }} - {{ item.name }} {{ item.age }} 歲 <input type="text">
    </li>
  </ul>

這裡值得一提的是運用了 .filter().match() 這兩個方法,可查詢相關文件
另外避免搞混,我們把 this 單獨宣告出來
這時候我們就可以過濾資料了

另外我們也可以輸出純數字的迴圈:

<ul>
    <li v-for="item in 10">
      {{ item }}
    </li>
</ul>

如果我們是 in 一個數字就是繞出一個數字的迴圈

再來我們可以使用 <template> 搭配 v-for 來做使用,<template> 是不會做輸出的
而我們的目的是一次輸出兩個 <tr>:

<table class="table">
    <template v-for="item in arrayData">
      <tr>
        <td>{{ item.age }}</td>
      </tr>
      <tr>
        <td>{{ item.name }}</td>
      </tr>
    </template>
</table>

v-for 內,有時候我們會搭配 v-if 來做使用,撈出符合判斷式的資料:

  <ul>
    <li v-for="(item, key) in arrayData" v-if="item.age <= 20">
      {{ key }} - {{ item.name }} {{ item.age }} 歲
    </li>
  </ul>

上面我們就新增了一個 v-if 並只顯示出年齡小於等於 20 歲的資料

另外在 Vue 裡面,有些狀況會無法運作,雖然是用 JS 的概念去寫,但仍然無法作用
我們一樣先把 arrayData 內的資料撈出來,並新增一個 cantWorkfunctionbutton 元素內
function 內的內容一樣補在最上面的 script

  <button class="btn btn-outline-primary" @click="cantWork">無法運行</button>
  <ul>
    <li v-for="(item, key) in arrayData" :key="item.age">
      {{ key }} - {{ item.name }} {{ item.age }} 歲 <input type="text">
    </li>
  </ul>

第一種不能運作的情況是當我們把 arrayData 的長度改為 0 的時候,照理說資料就會被刪光,可是當我們點擊 button 元素時,資料並沒有不見
第二種不能運作的情況是當我們把 arrayData 內的某筆資料進行改寫時,也會無效,但是針對這種情況有另外一種做法,可以使用 Vue.set() 這個在官方文件中有提到,我們可以使用 Vue.set() 強制改寫某筆資料,上述我也改寫了第一筆資料
以上就是無法運作的情況


上一篇
鐵人賽Day11 - 動態切換 class 和 style 多種方法
下一篇
鐵人賽Day13 - v-if 使用細節
系列文
新手初探 Vue30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言