先來(lái)一張圖看看:
隨意拖動(dòng)布局
隨意Resize
getLayout Api獲取當(dāng)前的布局信息
點(diǎn)擊以后卦尊,可以看到一個(gè)布局,這個(gè)布局擁有存儲(chǔ)能力尺棋,也就是當(dāng)你刷新瀏覽器以后,他的布局效果不會(huì)消失莱褒,無(wú)論是位置提佣,還是圖片大小。
項(xiàng)目地址:Github地址 (無(wú)恥求星7窖)
在線(xiàn)觀看(第一次加載需要等幾秒):預(yù)覽地址
說(shuō)起來(lái)不容易狭魂,人在國(guó)外沒(méi)有過(guò)年一說(shuō),但是畢竟也是中國(guó)年党觅,雖然不放假雌澄,但是家里總會(huì)主內(nèi)一頓豐盛的年夜飯。
說(shuō)吧杯瞻,人家在上班镐牺,我在家里過(guò)年,那肯定就不同步了魁莉。
不同步會(huì)發(fā)生什么睬涧?
拖拽組件
大概三四個(gè)月以前募胃,我寫(xiě)了一篇《「實(shí)戰(zhàn)」React實(shí)現(xiàn)的拖拽組件》,只不過(guò)畦浓,這個(gè)組件比較基礎(chǔ)痹束,僅僅支持電腦端的使用,而且不能支持拖拽排序宅粥,顯然不是很符合要求参袱。
也嘗試找了幾款組件,想改吧改吧就上了秽梅,但是一些組件都蠻老的了抹蚀,還是jQ的,不是很符合我們的技術(shù)棧企垦。
想想還是算了环壤,自己造一個(gè)輪子吧,反正我那么愛(ài)造輪子钞诡,順手寫(xiě)一個(gè)也無(wú)所謂郑现。
Typescript(TS)
最近一直在使用TS進(jìn)行開(kāi)發(fā),Eggjs的Ts實(shí)踐也寫(xiě)了一半荧降。這玩意兒接箫,真的是有毒的,因?yàn)槟茏屇闵习a朵诫。
隨便將一個(gè)項(xiàng)目遷移到TS之上辛友,在強(qiáng)大的靜態(tài)類(lèi)型檢測(cè)下,你就能輕松的發(fā)現(xiàn)一堆邏輯和邊界錯(cuò)誤剪返。一番重構(gòu)之后废累,頓時(shí)感覺(jué)代碼神清氣爽,頭皮恢復(fù)了生機(jī)脱盲!
所以邑滨,這款組件完全是用Typescript進(jìn)行開(kāi)發(fā),使得使用TS的小伙伴來(lái)說(shuō)钱反,更加方便快捷掖看。其次,如果你想使用Javascript開(kāi)發(fā)面哥,也是完全沒(méi)有問(wèn)題的乙各。
造輪子的一些思考
首先,我們的需求是用戶(hù)能夠方便的調(diào)整后臺(tái)dash board的各種表盤(pán)位置幢竹。
圖片來(lái)自:https://github.com/yezihaohao/react-admin
類(lèi)似一個(gè)這樣的界面耳峦,我們需要對(duì)其里面的組件進(jìn)行各種各樣的拖動(dòng)(不得不說(shuō)一句,他媽的焕毫,老子都做好了后臺(tái)系統(tǒng)你就用就可以了蹲坷,拖你妹啊驶乾,不讓人好好吃年夜飯。)
那么首先循签,我們就要考慮幾個(gè)點(diǎn):
- 技術(shù)棧是React
- 固定范圍(Container)內(nèi)的所有掛件不能超出這個(gè)范圍级乐。
- 每個(gè)掛件可以設(shè)定大小,并且按一定的margin上下分割開(kāi)县匠。
- Container內(nèi)的所有組件必須不能重疊风科,還要能自動(dòng)排序
- 某些組件要可以設(shè)定靜態(tài)的,也就是固定在那里乞旦,不被布局的任何變動(dòng)而影響贼穆。
- 手機(jī)也可以操作
動(dòng)手開(kāi)始
得益于之前寫(xiě)過(guò)拖拽組件,避開(kāi)了很多坑兰粉,也是寫(xiě)下這款組件故痊,主要有得特點(diǎn)是:
- React組件
- 自動(dòng)布局的網(wǎng)格系統(tǒng)
- 手機(jī)上也可以操作
- 高度自適應(yīng)
- 靜態(tài)組件(Live Demo(預(yù)覽地址))
- 可拖拽的組件(Live Demo(預(yù)覽地址))
終于在大年初二早上,弄完了這款組件玖姑,基本可以滿(mǎn)足客戶(hù)需求愕秫,然而還有一些TODO LIST:
- 水平交換模式,目前移動(dòng)的時(shí)候不是
- 用戶(hù)動(dòng)態(tài)調(diào)整每個(gè)掛件的大小焰络,就像Windows窗口一樣
- 掛件拖動(dòng)把手
- 支持響應(yīng)式
- 支持ssr戴甩,服務(wù)器渲染
如何開(kāi)始?
npm install --save dragact
寫(xiě)一個(gè)例子
//index.js
import * as React from "react";
import * as ReactDOM from "react-dom";
import { Dragact } from 'dragact';
import './index.css'
ReactDOM.render(
<Dragact
col={8}
width={800}
margin={[5, 5]}
rowHeight={40}
className='plant-layout'
>
<div key={0} data-set={{ GridX: 0, GridY: 0, w: 4, h: 2 }} className='layout-child'>0</div>
<div key={1} data-set={{ GridX: 0, GridY: 0, w: 1, h: 2 }} className='layout-child'>1</div>
<div key={2} data-set={{ GridX: 0, GridY: 0, w: 3, h: 2 }} className='layout-child'>2</div>
</Dragact>,
document.getElementById('root')
);
加點(diǎn)css
/** index.css */
.plant-layout {
border: 1px solid black;
}
.layout-child {
height: 100%;
background: #ef4;
display: flex;
justify-content: center;
align-items: center;
}
想要一個(gè)新的特色闪彼、功能甜孤?
如果你想添加一些新功能或者一些非常棒的點(diǎn)子,請(qǐng)發(fā)起issue告訴我备蚓,謝謝课蔬!
如果你已經(jīng)閱讀過(guò)源代碼囱稽,并且添加了一些非常牛X??的點(diǎn)子郊尝,請(qǐng)發(fā)起你的PR.
有bug?
如果你發(fā)現(xiàn)了本項(xiàng)目的Bug,請(qǐng)務(wù)必馬上告訴我战惊。添加一個(gè)issue流昏,并且?guī)兔o出最最簡(jiǎn)單重現(xiàn)的例子,這能讓我快速定位到Bug幫你解決吞获,謝謝况凉!
最后
這是2018年的第二個(gè)輪子了。
造輪子訓(xùn)練的能力當(dāng)然不是只有把輪子重新寫(xiě)一遍的能力各拷,還有一個(gè)很重要的因素就是:心態(tài)刁绒。
為什么我說(shuō)的是心態(tài)呢?我舉一個(gè)生活中的例子烤黍,你去新買(mǎi)一臺(tái)iPhone知市,假設(shè)以前根本沒(méi)有用過(guò)iPhone傻盟,買(mǎi)到手的時(shí)候,肯定會(huì)小心翼翼的去使用其中的功能嫂丙,基本上就是這個(gè)不敢設(shè)置娘赴,另外一個(gè)不敢設(shè)置,這個(gè)不敢按跟啤,那個(gè)不敢碰诽表。但是隨著時(shí)間久了,你熟悉了iPhone隅肥,每個(gè)角落都被你玩透了竿奏,你就不在乎了,隨便玩武福,隨便調(diào)议双,厲害的刷機(jī)越獄改主題。
這就是心態(tài)的變化捉片,應(yīng)用到編程之中也是如此平痰。剛開(kāi)始的時(shí)候,你拿到別人框架來(lái)用伍纫,非常的不熟練宗雇,跟著作者寫(xiě)的案例,設(shè)置成功莹规,解決了你的問(wèn)題赔蒲,你就不敢再碰那一段代碼了。隨后良漱,新的需求來(lái)了舞虱,你必須要在原有的基礎(chǔ)上加新功能,然而作者這時(shí)候因?yàn)槟承┰虿辉倬S護(hù)那個(gè)軟件了母市,你要么找新的矾兜,要么就是深入看代碼。
剛開(kāi)始的時(shí)候患久,你可能只是調(diào)整框架代碼里面的參數(shù)椅寺,隨著越來(lái)越的需求,你改的越來(lái)越多蒋失,這個(gè)框架你開(kāi)始熟悉返帕,逐漸逐漸的,你就壓根不怕需求來(lái)了篙挽,因?yàn)槟闾煜ち恕?/p>
這個(gè)過(guò)程相當(dāng)?shù)穆L(zhǎng)荆萤,聰明的人幾個(gè)月,比較笨的人或者懶惰的人铣卡,可能10年链韭。為了快速獲得這種心態(tài)的轉(zhuǎn)變邑闲,你要做的就是「造輪子」。這是一個(gè)最快的辦法梧油,也是最土最笨的辦法苫耸,但是確實(shí)是一個(gè)「必須有效的辦法」。