文章出處

前面的話

  Vue為了增加列表渲染的功能,增加了一組觀察數組的方法,而且可以顯示一個數組的過濾或排序的副本。本文將詳細介紹Vue數組更新及過濾排序

 

變異方法

  Vue 包含一組觀察數組的變異方法,它們將會觸發視圖更新,包含以下方法

push() 接收任意數量的參數,把它們逐個添加到數組末尾,并返回修改后數組的長度
pop() 從數組末尾移除最后一項,減少數組的length值,然后返回移除的項
shift() 移除數組中的第一個項并返回該項,同時數組的長度減1
unshift() 在數組前端添加任意個項并返回新數組長度
splice() 刪除原數組的一部分成員,并可以在被刪除的位置添加入新的數組成員
sort() 調用每個數組項的toString()方法,然后比較得到的字符串排序,返回經過排序之后的數組
reverse() 用于反轉數組的順序,返回經過排序之后的數組
<div id="example">
  <div>
    <button @click='push'>push</button>
    <button @click='pop'>pop</button>
    <button @click='shift'>shift</button>
    <button @click='unshift'>unshift</button>
    <button @click='splice'>splice</button>
    <button @click='sort'>sort</button>
    <button @click='reverse'>reverse</button>
  </div>
  <ul>
    <li v-for="item in items" >
      {{ item.message }}
    </li>
  </ul>  
</div>
<script>
var example = new Vue({
  el: '#example',
  data: {
    items: [
      {message: 'Foo' },
      {message: 'Bar' },
      {message: 'Baz' }
    ],
    addValue:{message:'match'}
  },
  methods:{
    push(){
      this.items.push(this.addValue)
    },
    pop(){
      this.items.pop()
    },
    shift(){
      this.items.shift()
    },
    unshift(){
      this.items.unshift(this.addValue)
    },
    splice(){
      this.items.splice(0,1)
    },
    sort(){
     this.items.sort()
    },
    reverse(){
      this.items.reverse()
    },
  }
})
</script>

 

非變異方法

  變異方法(mutation method),顧名思義,會改變被這些方法調用的原始數組。相比之下,也有非變異(non-mutating method)方法,例如: filter(), concat(), slice() 。這些不會改變原始數組,但總是返回一個新數組。當使用非變異方法時,可以用新數組替換舊數組

concat() 先創建當前數組一個副本,然后將接收到的參數添加到這個副本的末尾,最后返回新構建的數組
slice() 基于當前數組中一個或多個項創建一個新數組,接受一個或兩個參數,即要返回項的起始和結束位置,最后返回新數組
map() 對數組的每一項運行給定函數,返回每次函數調用的結果組成的數組
filter() 對數組中的每一項運行給定函數,該函數會返回true的項組成的數組
<div id="example">
  <div>
    <button @click='concat'>concat</button>
    <button @click='slice'>slice</button>
    <button @click='map'>map</button>
    <button @click='filter'>filter</button>
  </div>
  <ul>
    <li v-for="item in items" >
      {{ item }}
    </li>
  </ul>  
</div>
<script>
var example = new Vue({
  el: '#example',
  data: {
    items: ['Foo','Bar','Baz'],
    addValue:'match'
  },
  methods:{
    concat(){
      this.items =  this.items.concat(this.addValue)
    },
    slice(){
      this.items =  this.items.slice(1)
    },
    map(){
      this.items =  this.items.map(function(item,index,arr){
        return index + item; 
      })
    },
    filter(){
      this.items =  this.items.filter(function(item,index,arr){
        return (index > 0); 
      })
    }
  }
})
</script>

  以上操作并不會導致Vue丟棄現有DOM并重新渲染整個列表。Vue實現了一些智能啟發式方法來最大化DOM元素重用,所以用一個含有相同元素的數組去替換原來的數組是非常高效的操作

 

無法檢測

  由于JS的限制, Vue 不能檢測以下變動的數組:

  1、利用索引直接設置一個項時,例如: vm.items[indexOfItem] = newValue

  2、修改數組的長度時,例如: vm.items.length = newLength

<div id="example">
  <div>
    <button @click='setVal'>setVal</button>
    <button @click='setLength'>setLength</button>
    <button @click='pop'>pop</button>
  </div>
  <ul>
    <li v-for="item in items" >{{ item }}</li>
  </ul> 
  <p>{{ message }}</p> 
</div>
<script>
var watchFunc = function(){
  example.message = '數據發生變化';
  setTimeout(function(){
    example.message = '';
  },500); 
}
var example = new Vue({
  el: '#example',
  data: {
    items: ['Foo','Bar','Baz'],
    message:'',
  },
  watch:{
    items:watchFunc
  },
  methods:{
    pop(){
      this.items.pop()
    },
    setVal(){
      this.items[0]= 'match';
    },
    setLength(){
      this.items.length = 2;
    }
  }
})
</script>

  以上代碼中,直接設置值和長度使用watch不能檢測到變化

  以下兩種方式都可以實現和vm.items[indexOfItem]=newValue相同的效果, 同時也將觸發狀態更新

// Vue.set
Vue.set(example1.items, indexOfItem, newValue)
// Array.prototype.splice
example1.items.splice(indexOfItem, 1, newValue)

   為了解決第二類問題,可以使用 splice

example1.items.splice(newLength)
<div id="example">
  <div>
    <button @click='setVal1'>setVal1</button>
    <button @click='setVal2'>setVal2</button>
    <button @click='setLength'>setLength</button>
  </div>
  <ul>
    <li v-for="item in items" >{{ item }}</li>
  </ul> 
  <p>{{ message }}</p> 
</div>
<script>
var watchFunc = function(){
  example.message = '數據發生變化';
  setTimeout(function(){
    example.message = '';
  },500); 
}
var example = new Vue({
  el: '#example',
  data: {
    items: ['Foo','Bar','Baz'],
    message:'',
  },
  watch:{
    items:watchFunc
  },
  methods:{
    setVal1(){
      Vue.set(this.items, 0, 'match')
    },
    setVal2(){
      this.items.splice(1, 1, 'xiaohuochai')
    },    
    setLength(){
      this.items.splice(2)
    }
  }
})
</script>

 

過濾排序

  有時,要顯示一個數組的過濾或排序副本,而不實際改變或重置原始數據。在這種情況下,可以創建返回過濾或排序數組的計算屬性

【computed】

<div id="example">
  <ul>
    <li v-for="n in evenNumbers">{{ n }}</li>
  </ul> 
</div>
<script>
var example = new Vue({
  el: '#example',
  data: {
    numbers: [ 1, 2, 3, 4, 5 ],
  },
  computed: {
    evenNumbers: function () {
      return this.numbers.filter(function (number) {
        return number % 2 === 0
      })
    }
  }
})
</script>

【methods】

  在計算屬性不適用的情況下 (例如,在嵌套 v-for 循環中) 可以使用一個 method 方法

<div id="example">
  <ul>
    <li v-for="n in even(numbers)">{{ n }}</li>
  </ul> 
</div>
<script>
var example = new Vue({
  el: '#example',
  data: {
    numbers: [ 1, 2, 3, 4, 5 ],
  },
  methods: {
    even: function (numbers) {
      return numbers.filter(function (number) {
        return number % 2 === 0
      })
    }
  }
})
</script>

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()