用Vue實現(xiàn)一個全選指令

最近用vue做了兩個項目刹淌,都需要實現(xiàn)全選反選的功能饶氏,兩個項目用了兩種實現(xiàn)方法,第一個項目用vue的computed有勾,第二個項目用指令來實現(xiàn)疹启,用起來,發(fā)覺指令更加方便蔼卡。

第一次做全選的時候是剛開始接觸vue不久喊崖,全選的實現(xiàn)參考了知乎(鏈接:https://www.zhihu.com/question/37833194/answer/91812053)上的實現(xiàn)方法:

1、從服務(wù)器拿到數(shù)據(jù)雇逞,為每個item設(shè)置checked屬性

2荤懂、計算選中的數(shù)量selectCount,如果選中的數(shù)量與selectItems的數(shù)量相等,則全選selectAll選中

3塘砸、點全選時节仿,將每個item的checked屬性置為true,反選時置為false掉蔬,

4廊宪、每次selectItems的屬性發(fā)生變化時查近,都將checked的為true的item放入數(shù)組checkedGroups中

下面為實現(xiàn)代碼:

//全選

data: function() {

return {

selectItems: [],? // 從服務(wù)器拿到的數(shù)據(jù)

}

},

computed: {

// 全選checkbox綁定的model

selectAll: {

get: function() {

return this.selectCount == this.selectItems.length;

},

set: function(value) {

this.selectItems.forEach(function(item) {

item.checked = value;

});

return value;

}

},

//選中的數(shù)量

selectCount: {

get: function() {

var i = 0;

this.selectItems.forEach(function(item) {

if (item.checked) {

i++;

}

});

return i;

}

},

//選中的數(shù)組

checkedGroups: {

get: function() {

var checkedGroups = [];

this.selectItems.forEach(function(item) {

if (item.checked) {

checkedGroups.push(item);

}

});

return checkedGroups;

}

}

}

這種方法用起來不太方便,首先是很難復(fù)用挤忙,每次要用到的時候都需要寫一次computed霜威,其次是selectAll、checkedGroups册烈、selectItems都已經(jīng)固定戈泼,不太靈活。

所以在這次項目中赏僧,我用vue的指令重新實現(xiàn)了全選的功能大猛,directive的思路其實跟computed差不多,先上代碼:

export default {

'check-all': {

twoWay: true,

params: ['checkData'],

bind() {

/**

- 如果所有的列表的checked屬性都為true,則選中全選框,否則不選中全選框

*/

this.vm.$watch(this.params.checkData, (checkData) => {

if (checkData.every((item) => item.checked)) {

this.set(true);

} else {

this.set(false);

}

}, { deep: true });

},

// checkAll發(fā)生更改時

update(checkAll) {

/**

- 如果全選框被選中,則將列表的所有checked屬性轉(zhuǎn)為true,否則轉(zhuǎn)為false

*/

if (checkAll) {

this.vm[this.params.checkData].forEach((item) => {

item.checked = true;

});

} else {

this.vm[this.params.checkData].forEach((item) => {

item.checked = false;

});

}

},

},

};

調(diào)用:

{{item.text}}

先說說這樣用的優(yōu)點:

1淀零、方便使用挽绩,在需要用的地方,寫上v-check-all指令和check-data就可以

2驾中、全選的model和數(shù)組名可以定制唉堪,用什么名字都可以,全選的model不想叫checkAll叫checkAllData也可以肩民,數(shù)組不想叫checkData叫dataFromServer也可以唠亚。

在指令中,指定twoWay為true,就可以用this.set(value)來設(shè)置checkAll的值持痰,用params接收綁定指令元素上的屬性值checkData,也就是需要操作的數(shù)組灶搜。

用this.vm獲取使用指令的上下文,調(diào)用上下文的$watch來監(jiān)聽checkData的變化工窍,如果checkData全部選中割卖,則設(shè)置checkAll為true,否則設(shè)置checkAll為false患雏。

當(dāng)指令值(checkAll)發(fā)生變化鹏溯,如果為true沼琉,則將checkData的checked屬性都設(shè)為true腻扇,否則為false挺狰。至此爽蝴,一個全選的指令就完成了惑艇。

在做這個全選指令的時候煮落,本來想用paramWatchers來監(jiān)聽checkData的變化的罩驻,但是發(fā)覺checkData變動時悔常,并不會觸發(fā)paramWatchers的回調(diào)怀吻,后來看了一下源碼才發(fā)現(xiàn)瞬浓,paramWatchers其實也是調(diào)用了$watch,但是不支持深度檢測:

Directive.prototype._setupParamWatcher = function (key, expression) {

var self = this;

var called = false;

var unwatch = (this._scope || this.vm).$watch(expression, function (val, oldVal) {

self.params[key] = val;

// since we are in immediate mode,

// only call the param change callbacks if this is not the first update.

if (called) {

var cb = self.paramWatchers && self.paramWatchers[key];

if (cb) {

cb.call(self, val, oldVal);

}

} else {

called = true;

}

}, {

immediate: true,

user: false

});(this._paramUnwatchFns || (this._paramUnwatchFns = [])).push(unwatch);

};

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蓬坡,一起剝皮案震驚了整個濱河市猿棉,隨后出現(xiàn)的幾起案子磅叛,更是在濱河造成了極大的恐慌,老刑警劉巖萨赁,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件弊琴,死亡現(xiàn)場離奇詭異,居然都是意外死亡杖爽,警方通過查閱死者的電腦和手機敲董,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來慰安,“玉大人腋寨,你說我怎么就攤上這事』溃” “怎么了萄窜?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長撒桨。 經(jīng)常有香客問我查刻,道長,這世上最難降的妖魔是什么元莫? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任赖阻,我火速辦了婚禮,結(jié)果婚禮上踱蠢,老公的妹妹穿的比我還像新娘。我一直安慰自己棋电,他們只是感情好茎截,可當(dāng)我...
    茶點故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著赶盔,像睡著了一般企锌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上于未,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天撕攒,我揣著相機與錄音,去河邊找鬼烘浦。 笑死抖坪,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的闷叉。 我是一名探鬼主播擦俐,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼握侧!你這毒婦竟也來了蚯瞧?” 一聲冷哼從身側(cè)響起嘿期,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎埋合,沒想到半個月后备徐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡甚颂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年坦喘,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片西设。...
    茶點故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡瓣铣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出贷揽,到底是詐尸還是另有隱情棠笑,我是刑警寧澤,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布禽绪,位于F島的核電站蓖救,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏印屁。R本人自食惡果不足惜循捺,卻給世界環(huán)境...
    茶點故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望雄人。 院中可真熱鬧从橘,春花似錦、人聲如沸础钠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽旗吁。三九已至踩萎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間很钓,已是汗流浹背香府。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留码倦,地道東北人企孩。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像叹洲,于是被迫代替她去往敵國和親柠硕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,562評論 2 349

推薦閱讀更多精彩內(nèi)容

  • 下載安裝搭建環(huán)境 可以選npm安裝,或者簡單下載一個開發(fā)版的vue.js文件 瀏覽器打開加載有vue的文檔時蝗柔,控制...
    冥冥2017閱讀 6,033評論 0 42
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理闻葵,服務(wù)發(fā)現(xiàn),斷路器癣丧,智...
    卡卡羅2017閱讀 134,633評論 18 139
  • 工廠模式類似于現(xiàn)實生活中的工廠可以產(chǎn)生大量相似的商品槽畔,去做同樣的事情,實現(xiàn)同樣的效果;這時候需要使用工廠模式胁编。簡單...
    舟漁行舟閱讀 7,726評論 2 17
  • 猴年除夕那天的團年飯是在我家附近的一家餐館吃的厢钧。 說實在話,餐館里的飯菜自然比不上自家里的更合口味嬉橙≡缰保可在餐館吃,為...
    健哥0256閱讀 460評論 2 4
  • 2016年12月5日1.JIRA文檔位置創(chuàng)建錯誤市框,如何移動選擇編輯移動 2016年10月31日1.ios最新版本a...
    wangyu2488閱讀 7,143評論 0 4