vue指令封裝2:全局保存dom狀態(tài)的指令

之前對(duì)代碼中直接調(diào)用DragMove的過程進(jìn)行了封裝匪凡,把它轉(zhuǎn)移到v-dragmove指令中巡李。一切都很美好,數(shù)據(jù)到dom在模板里笆呆,數(shù)據(jù)的處理在組件里请琳。

傳送門: http://www.reibang.com/p/5b20207be9de

之后,寧哥又提了一個(gè)需求赠幕,現(xiàn)在項(xiàng)目中有很多需要記錄位置的功能俄精,這些與業(yè)務(wù)無關(guān)的功能侵蝕了業(yè)務(wù)代碼,使得業(yè)務(wù)代碼臃腫而每次都要做一些重復(fù)的開發(fā)榕堰,這些邏輯能封裝到里面么竖慧?

我說可以啊,不過這樣指令就不只是調(diào)用一下目標(biāo)方法逆屡,參數(shù)坐下適配的適配器的工作了圾旨,多加了一個(gè) 保存位置的代理的功能。這樣這個(gè)指令就相當(dāng)于 適配器 + 代理了魏蔗。


具體需求是這樣的:路由切換砍的,組件會(huì)銷毀,在切換回來莺治,組件會(huì)重新創(chuàng)建挨约。要求可以在切換回來的時(shí)候恢復(fù)之前的拖動(dòng)位置味混。

分析:恢復(fù)之前的位置需要一個(gè)全局的地方來保存這個(gè)位置,并且需要用唯一的id來關(guān)聯(lián)組件诫惭,位置可以保存在vuex、localStorage蔓挖、自己維護(hù)的一個(gè)內(nèi)存中的數(shù)據(jù)結(jié)構(gòu)等夕土。 這里的數(shù)據(jù)是與業(yè)務(wù)無關(guān)的,而且指令不應(yīng)該依賴vuex瘟判,所以怨绣,我自己維護(hù)了一個(gè)position的Map,而id的話拷获,用元素的id就可以了篮撑,剛好滿足唯一和關(guān)聯(lián)組件兩個(gè)需求。剩下的就是在 dragEndHandler加上保存位置匆瓜、在指令所作用的元素剛插入父元素(inserted方法)時(shí)恢復(fù)位置赢笨。

可視化表達(dá)一下:

代碼如下:


import DragMove from 'drag-move';

const install = (Vue) => {

    //所有的拖動(dòng)位置信息
    const positionMap = new Map();
    
    //重置位置
    const resetPosition = (element, positionId) => {
        if (positionMap.has(positionId)) {
            const position = positionMap.get(positionId);
            element.style += `;left:${position.left}px;top:${position.top}px;`;
        }
    }

    //保存位置
    const savePosition = (positionId, position) => {
        positionMap.set(positionId, position);
    } 

    //代理拖動(dòng)結(jié)束handler
    const proxyDragEndHandler = (dragEndHandler, positionId) => {
        return (position) => {
            savePosition(positionId, position);
            dragEndHandler.apply(null, position);
        }
    }

    /**
     * dragmove指令
     * 用法: <div id='ele' v-dragmove:ele="{dragend:dragendHandler}"></div>
     */
    Vue.directive('dragmove', {
        inserted(el, binding) {
            const options = {...binding.value, id: binding.arg};
            const positionId = options.id;

            resetPosition(el, positionId);

            if (binding.modifiers.save) {
                let dragEndHandler = options.dragend || function() {};
                options.dragend = proxyDragEndHandler(dragEndHandler, positionId);
            }

            new DragMove(options);
        }
    });
}
module.exports = install;

這里的positionMap就是全局位置數(shù)據(jù)存儲(chǔ)的地方,savePosition和resetPosition就是組件和positionMap之間交流position數(shù)據(jù)的方法驮吱。

經(jīng)過測(cè)試茧妒,是可以滿足需求的,用法如下:

  v-dragmove:id.save="{}"
  v-dragmove:id="{}"

帶.save修飾符的會(huì)保存位置左冬,否則不會(huì)桐筏。

不過這里有兩個(gè)需要注意的地方,一是因?yàn)閕d直接用的元素id拇砰,需要保證元素id全局唯一梅忌,二是this的問題,如果handler里面用到了this除破,需要手動(dòng)bind一下

v-dragmove:id.save="{dragend:dragEndHanlder.bind(this)}"

封裝的價(jià)值

對(duì)比下重構(gòu)前后的原理圖

沒封裝成指令之前:

封裝成指令之后:

你會(huì)發(fā)現(xiàn)其實(shí)只是把邏輯移動(dòng)了個(gè)位置牧氮,都封裝到指令里,這樣皂岔,會(huì)使得整體可復(fù)用蹋笼。而不是分散的寫多份。封裝的意義就是復(fù)用躁垛。

可以刪掉的一些代碼:

組件中業(yè)務(wù)無關(guān)的邏輯少了很多

收獲

總結(jié)一下開發(fā)這個(gè)指令的收獲:

  1. 參數(shù)放到 value和arg里剖毯, 其余的一些控制放到modifer里
    如:v-example:arg.a.b.c="value", 這里通過a教馆、b逊谋、c來控制功能,value和arg來傳參

  2. 指令不應(yīng)該依賴vuex土铺,也不要依賴localStorage胶滋,需要全局?jǐn)?shù)據(jù)的時(shí)候應(yīng)該自己維護(hù)一個(gè)內(nèi)存中的數(shù)據(jù)結(jié)構(gòu)板鬓,比如這里的positionMap。這樣的指令才是通用的究恤。

  3. 指令的職責(zé)應(yīng)該單一俭令,比如dragmove這個(gè)指令就只是封裝了拖動(dòng)相關(guān)的邏輯,包括拖動(dòng)位置的保存部宿。

4.vue的指令有一個(gè)坑抄腔,當(dāng)兩個(gè)指令同時(shí)修改了一個(gè)屬性的時(shí)候,沒法保證順序理张,所以dragmove的初始位置是用css設(shè)置的赫蛇,之后通過指令修改style

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市雾叭,隨后出現(xiàn)的幾起案子悟耘,更是在濱河造成了極大的恐慌,老刑警劉巖织狐,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件暂幼,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡赚瘦,警方通過查閱死者的電腦和手機(jī)粟誓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來起意,“玉大人鹰服,你說我怎么就攤上這事±抗荆” “怎么了悲酷?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)亲善。 經(jīng)常有香客問我设易,道長(zhǎng),這世上最難降的妖魔是什么蛹头? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任顿肺,我火速辦了婚禮,結(jié)果婚禮上渣蜗,老公的妹妹穿的比我還像新娘屠尊。我一直安慰自己,他們只是感情好耕拷,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布讼昆。 她就那樣靜靜地躺著,像睡著了一般骚烧。 火紅的嫁衣襯著肌膚如雪浸赫。 梳的紋絲不亂的頭發(fā)上闰围,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音既峡,去河邊找鬼羡榴。 笑死,一個(gè)胖子當(dāng)著我的面吹牛涧狮,可吹牛的內(nèi)容都是我干的炕矮。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼者冤,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了档痪?” 一聲冷哼從身側(cè)響起涉枫,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎腐螟,沒想到半個(gè)月后愿汰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡乐纸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年衬廷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片汽绢。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡吗跋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出宁昭,到底是詐尸還是另有隱情跌宛,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布积仗,位于F島的核電站疆拘,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏寂曹。R本人自食惡果不足惜哎迄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望隆圆。 院中可真熱鬧漱挚,春花似錦、人聲如沸匾灶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽阶女。三九已至颊糜,卻和暖如春哩治,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背衬鱼。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工业筏, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鸟赫。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓蒜胖,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親抛蚤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子台谢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

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

  • 前言 您將在本文當(dāng)中了解到,往網(wǎng)頁中添加數(shù)據(jù),從傳統(tǒng)的dom操作過渡到數(shù)據(jù)層操作,實(shí)現(xiàn)同一個(gè)目標(biāo),兩種不同的方式....
    itclanCoder閱讀 25,806評(píng)論 1 12
  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內(nèi)容,還有我對(duì)于 Vue 1.0 印象不深的內(nèi)容岁经。關(guān)于...
    云之外閱讀 5,050評(píng)論 0 29
  • “心理學(xué)有著漫長(zhǎng)的過去,但只有短暫的歷史塘慕〗钕模”最早的實(shí)驗(yàn)心理學(xué)家之一艾賓浩斯這樣寫道。因?yàn)橥寄兀缭诠畔ED時(shí)就已經(jīng)有了心...
    楊柳軒軒閱讀 32,954評(píng)論 19 40
  • 首先每天打卡条篷! 4個(gè)鏈接 邀約妮妮媽參加分享會(huì),和娟鏈接岳瞭,和bobbi鏈接拥娄,幫助會(huì)員柳青辦會(huì)員 1次分享 朋友圈和...
    汪安安閱讀 289評(píng)論 0 0
  • 1. 感恩早晨清涼的空氣,鍛煉看書很舒服瞳筏。感恩稚瘾! 2. 感恩滴滴順風(fēng)車的師傅將我們安全快捷地送到要去的地方。感恩姚炕!...
    李敏自然養(yǎng)娃閱讀 133評(píng)論 0 0