上述這個需求,我們可以使用兩種方式或者更多的方式實現,我們這裡採用計算屬性和監視屬性來寫
該API內部需要接受一個引數,這個引數型別是函數型別
原生js提供的一個過濾資料的API
寫個用法吧
const array = [14, 17, 18, 32, 33, 16, 40];
let newArr = array.filter(function(item){
// item 就是該陣列當中的每一項
// 該API需要提供一個返回值,這個返回值是一個判定條件
return item > 14
})
// 最終結果 newArr = [17,18,32,33,16,40] 將14過濾掉了
filter並不會改變原有陣列的結構,會返回一個新的陣列
使用計算屬性來實現可能要麻煩點,但是我會詳細的把步驟寫下來
計算屬性是vue當中的一個設定項,computed
computed當中,計算屬性由兩部分組成(key:{} == 屬性名,型別為物件)
computed:{
Calculate:{
}
}
書寫方式兩種,如果不需要對計算屬性進行修改,那麼可以捨棄set設定項的編寫,從而將計算屬性寫為函數形式,函數內部的內容代表的就是get設定項的內容
get設定項
set設定項
computed:{
Calculate:{
get(){
},
set(){
}
}
}
綜上所述,這個功能要被實現,那麼計算屬性必須要出現在頁面當中,並且該計算屬性還需要繫結一個或者多個 依賴屬性
當所依賴的屬性發生修改的時候,計算屬性的get呼叫,而我們的模糊查詢,就在get當中實現
在get當中實現,那麼就可以使用計算屬性的簡寫形式
html
<!-- 建立一個容器 -->
<div class="app">
<!-- 模糊查詢 -->
<input type="text" v-model="keyWords">
<!-- 列表渲染 -->
<ul>
<li v-for="item in filterPersons" :key="item.id">
{{item.name}} - {{item.age}} - {{item.sex}}
</li>
</ul>
</div>
js
<script>
const vm = new Vue({
el: '.app',
data: {
name: 'wavesbright',
keyWords:"",
// 原始資料
persons:[
{id:1,name:'馬冬梅',age:18,sex:"女"},
{id:2,name:"周冬雨",age:19,sex:"女"},
{id:3,name:"周杰倫",age:20,sex:"男"},
{id:4,name:"溫兆倫",age:21,sex:"男"},
],
},
methods: {
},
// 計算屬性
computed:{
// key:{} == 屬性名,型別為物件
filterPersons(){
return this.persons.filter((item) => {
return item.name.indexOf(this.keyWords) != -1
})
}
}
});
</script>
注意觀察 右邊資料的變化
是vue的一個設定項
內部採用 鍵值對來設定屬性
watch:{
keyWords:{
// 設定項1
// 設定項2
// 設定項3
}
}
內部有很多設定項,以handler這個設定項為主
handler是一個函數型別
當資料發生改變的時候呼叫該設定項
watch:{
keyWords:{
// 設定項1
// 設定項2
// 設定項3
handler(newValue,oldValue){
// 新資料,原始資料
}
}
}
watch的寫法有兩種
我們等下使用$watch書寫
html
與之前計算屬性一樣,但是這次不需要額外的span標籤了,因為我們只對keyWords進行監視
<!-- 建立一個容器 -->
<div class="app">
<!-- 模糊查詢 -->
<input type="text" v-model="keyWords">
<!-- 列表渲染 -->
<ul>
<li v-for="item in initialArr" :key="item.id">
{{item.name}} - {{item.age}} - {{item.sex}}
</li>
</ul>
</div>
js
// 我很明確我要監視的屬性是keyWords
vm.$watch("keyWords",function(newValue){
// 內部書寫的就是handler函數的內容
this.initialArr = this.persons.filter((item) => {
return item.name.indexOf(this.keyWords) != -1
})
})
我感覺這個API我用起來不是很順暢
我自己寫一個看看
這是api參考手冊
這是我們剛剛範例當中使用的filter
拋開其他的不談,filter 本質上就是 原型Array上的一個函數 == api
這個api的結構是這樣的
// 這個percolator是一個匿名函數
function filter(percolator){
}
那麼重點就在這個percolator 身上,它是一個引數,是一個匿名函數
這個匿名函數有三個引數,對應的就是檔案上的三個引數
把這個搞清楚了,剩下的就很簡單了
首先我們需要在原型物件Array當中,通過prototype 設計一個供 所有陣列型別,呼叫的函數
Array.prototype.myFilter = function(percolator){}
既然這個 方法,最終會得到一個新的陣列,不會改變原有陣列結構,那我們肯定要先設計一個新陣列嘛
Array.prototype.myFilter = function(percolator){
// 設計一個新陣列
let newArr = [];
}
我們需要得到 currentValue(迴圈項),這個東西到底如何上手?通過迴圈得到嘛
通過剛剛在原形物件上設計的 myFilter 函數,我們可以對這個陣列進行基本的迭代
Array.prototype.myFilter = function(percolator){
// 設計一個新陣列
let newArr = [];
// 對當前陣列進行迭代;this的指向是陣列本身
for(let i =0; i<this.length; i++){
// this[i] 就代表我們當前的迴圈項,也就是currentValue
}
}
this[i] 就代表我們當前的迴圈項,也就是currentValue
那麼現在,值得思考的地方就來了
所以現在結果很明確,我們需要寫個if判斷,當if為true,執行if當中的語句,控制是否為true,交給匿名函數 == percolator 來搞定
Array.prototype.myFilter = function(percolator){
// 設計一個新陣列
let newArr = [];
// 對當前陣列進行迭代;this的指向是陣列本身
for(let i =0; i<this.length; i++){
// this[i] 就代表我們當前的迴圈項,也就是currentValue
if(percolator(this[i],i,this)){ // 當前元素,當前索引,對應陣列
// 滿足條件,給 newArr新增一個元素
newArr.push(this[i]);
}
}
// 迴圈結束,返回新的陣列
return newArr;
}
這裡有一個簡單結構的陣列
現在我們呼叫api,myFilter,列印輸出