国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

徒手?jǐn)]UI之DatePicker

zilu / 1383人閱讀

摘要:是一個(gè)組件庫(kù)目前擁有的組件語(yǔ)法編寫(xiě),無(wú)依賴原生模塊化,以上支持,請(qǐng)開(kāi)啟靜態(tài)服務(wù)器預(yù)覽效果,靜態(tài)服務(wù)器傳送門(mén)采用變量配置樣式辛苦造輪子,歡迎來(lái)倉(cāng)庫(kù)四月份找工作,求內(nèi)推,坐標(biāo)深圳寫(xiě)在前面去年年底項(xiàng)目中嘗試著寫(xiě)過(guò)一個(gè)分頁(yè)的組件,然后就有了寫(xiě)的想法

QingUI是一個(gè)UI組件庫(kù)
目前擁有的組件:DatePicker, TimePicker, Paginator, Tree, Cascader, Checkbox, Radio, Switch, InputNumber, Input
ES6語(yǔ)法編寫(xiě),無(wú)依賴
原生模塊化,Chrome63以上支持,請(qǐng)開(kāi)啟靜態(tài)服務(wù)器預(yù)覽效果,靜態(tài)服務(wù)器傳送門(mén)
采用CSS變量配置樣式
辛苦造輪子,歡迎來(lái)github倉(cāng)庫(kù)star:https://github.com/veedrin/qing
四月份找工作,求內(nèi)推,坐標(biāo)深圳
寫(xiě)在前面

去年年底項(xiàng)目中嘗試著寫(xiě)過(guò)一個(gè)分頁(yè)的Angular組件,然后就有了寫(xiě)QingUI的想法

過(guò)程還是非常有意思的

接下來(lái)我會(huì)用幾篇文章分別介紹每個(gè)組件的大概思路,請(qǐng)大家耐心等待

這一篇介紹DatePicker日期選擇器

最重要的,求star,求fork,求內(nèi)推

https://github.com/veedrin/qing
少?gòu)U話,先上圖

實(shí)現(xiàn)一個(gè)類

ES6的類語(yǔ)法糖非常順手,用ES6寫(xiě)代碼就像吃德芙巧克力一樣哈哈

然后DatePicker和TimePicker有一些公共的方法,我用一個(gè)公共類,讓它們倆繼承

extends就是繼承關(guān)鍵字

super是用來(lái)繼承父類的this對(duì)象的,它必須首先調(diào)用,否則無(wú)法找到this

主要是為了照顧對(duì)ES6不熟悉的人

class Common {
    constructor() {}
}

class DatePicker extends Common {
    constructor() {
        super();
    }
}
日歷

不知道大家觀察過(guò)沒(méi)有,每一頁(yè)日歷都是按星期來(lái)排的,展示當(dāng)月的所有日期

所以,如果該月的1號(hào)不是星期一或者星期天呢?那還要從上個(gè)月抓幾天過(guò)來(lái),把空補(bǔ)齊,月底也一樣

為了方便,下面都以星期一為一周起始日

當(dāng)月所有日期容易,獲取當(dāng)月有多少天,for循環(huán)加到模板里

那月首補(bǔ)齊的呢?我要知道這個(gè)月1號(hào)是星期幾,還要知道上個(gè)月最后一天是多少號(hào),然后少幾天,往前推幾天就好了

月底補(bǔ)齊的就簡(jiǎn)單一點(diǎn),我要知道這個(gè)月最后一天是星期幾,然后少幾天,從1號(hào)往后加幾天

const daysCountThisMonth = this.daysCountThisMonth();
const daysCountLastMonth = this.daysCountThisMonth(-1);
// weekie指的是星期幾(自創(chuàng))
const weekieFirstDay = this.weekieOfSomedayThisMonth(1);
const weekieLastDay = this.weekieOfSomedayThisMonth(daysCountThisMonth);

if (weekieFirstDay > 1) {
    for (let i = daysCountLastMonth - weekieFirstDay + 2; i <= daysCountLastMonth; i++) {
        tpl += `${i}`;
    }
}
for (let i = 1; i <= daysCountThisMonth; i++) {
    tpl += `${i}`;
}
if (weekieLastDay < 7) {
    for (let i = 1; i <= 7 - weekieLastDay; i++) {
        tpl += `${i}`;
    }
}

這個(gè)月有多少天怎么算?

月份參數(shù)傳入下個(gè)月,日期參數(shù)傳入0,就可以獲得當(dāng)月最后一天是多少號(hào)了

我這里this.M就是當(dāng)月,而程序的月份是要減1的,所以就相當(dāng)于下個(gè)月了

某一天是星期幾好求,我就不列出來(lái)了

function daysCountThisMonth(num = 0) {
    return new Date(this.Y, this.M + num, 0).getDate();
}

至此,加上flex布局,一個(gè)靜態(tài)的日歷就做出來(lái)了

還有一個(gè)小細(xì)節(jié),我選中的日期要高亮,當(dāng)天也要有一個(gè)背景色,它們倆在初始的時(shí)候還應(yīng)該是重合的

當(dāng)天嘛,我緩存的年月和實(shí)時(shí)獲取的年月相等,再把實(shí)時(shí)獲取的日期和i比對(duì),就是當(dāng)天,加個(gè)today的class

而如果實(shí)時(shí)獲取的日期和緩存的日期還相等,那么這天不僅是當(dāng)天,還是用戶選中的日子,加個(gè)today active的class

剩下的就是用戶選中的不是當(dāng)天,和完全普通的日子

由于選擇年月的時(shí)候,日歷都要重新渲染,所以我們只能根據(jù)這些條件來(lái)判斷,看起來(lái)確實(shí)有些復(fù)雜

for (let i = 1; i <= daysCountThisMonth; i++) {
    if (this.Y === Y && this.M === M && i === D && i !== this.D) {
        tpl += `${i}`;
    } else if (this.Y === Y && this.M === M && i === D && i === this.D) {
        tpl += `${i}`;
    } else if (i === this.D) {
        tpl += `${i}`;
    } else {
        tpl += `${i}`;
    }
}

我之前以為實(shí)例化時(shí)把當(dāng)前年月日緩存起來(lái),然后再把用戶選中的年月日緩存起來(lái),兩者一對(duì)比,就可以渲染了

其實(shí)我沒(méi)有注意到一個(gè)問(wèn)題,就是使用日歷是有可能跨天的,理論上,如果永遠(yuǎn)不關(guān)機(jī),跨年都可以

如果我在午夜12點(diǎn)左右操作QingUI,那緩存的日期就有可能不準(zhǔn)確,因?yàn)橐呀?jīng)跨天了

至于我是如何發(fā)現(xiàn)這個(gè)BUG的,你猜?

所以每次渲染都要實(shí)時(shí)獲取當(dāng)前年月日

ES6的解構(gòu)賦值可以讓這個(gè)操作非常優(yōu)美

function nowDate() {
    const date = new Date();
    return [date.getFullYear(), date.getMonth() + 1, date.getDate()];
}

const [Y, M, D] = nowDate();

話說(shuō)就因?yàn)檫@個(gè)BUG,我?guī)缀踔貥?gòu)了整個(gè)組件

最后,用戶選中高亮是通過(guò)添加class的方式實(shí)現(xiàn)的,高亮新的日子,然后把舊的日子高亮去掉

注意,這種操作是不需要重新渲染的,所以一般做法是,把所有日子循環(huán)一遍,去掉高亮,然后添加新的高亮

如果我們將上一個(gè)高亮的日子緩存起來(lái)呢?是不是就不用每次for循環(huán)了,于是就有了this.oldD

三角選擇年月

選擇年月有兩種方式,一種是點(diǎn)開(kāi)面板,直接選擇,一種是點(diǎn)擊三角,每次增1或減1

點(diǎn)擊三角的時(shí)候,我設(shè)置成1月再減1,就會(huì)變成年份減1,月份變成12月,也就是說(shuō)月份是可以一直點(diǎn)的

// 置灰時(shí)獲取不到元素
if ($monthPrev) {
    $monthPrev.addEventListener("click", function(event) {
        event.stopPropagation();
        self.M--;
        if (self.M > 0) {
            self.yearAndMonthChange("month");
        } else {
            self.M = 12;
            self.Y--;
            self.yearAndMonthChange("both");
        }
    });
}

可真的是這樣嗎?還記得有一個(gè)配置項(xiàng)yearRange嗎?

如果年份到了頭,就置灰不能再點(diǎn)了,這是我遇到的第二個(gè)坑

如果年份到了頭,年份的減三角就要置灰,但是月份的減三角還是可以點(diǎn)

直到月份變成1,那么年份和月份的減三角都置灰了

加三角的邏輯也一樣

這個(gè)邏輯,你們理一理

const [left, right] = this.yearRange;

let tpl = `
    
? ?
? ?
`;
面板選擇年月

選擇年份和月份面板,我之前是做成pop彈窗加滾動(dòng)條的,發(fā)現(xiàn)體驗(yàn)很糟糕,于是參考ElementUI做到了日歷面板上

這就帶來(lái)一個(gè)問(wèn)題,顯示年份面板的時(shí)候,日歷實(shí)際上是清除了,選擇完以后再重新渲染日歷,繼續(xù)重構(gòu)...

月份簡(jiǎn)單,一個(gè)面板就顯示完了

年份有可能一個(gè)面板顯示不完,但再怎么樣,也比年份和月份聯(lián)動(dòng)的情況要簡(jiǎn)單是吧

我把用戶選擇的年份緩存起來(lái),因?yàn)槲蚁M延脩暨x中過(guò)的年份放在比較中間的位置,他下次再選的時(shí)候,可以從這里繼續(xù)

再結(jié)合yearRange,效果是這樣的

const [left, right] = this.yearRange;
const start = this.anchor - 4 > left ? this.anchor - 4 : left;
const end = this.anchor + 7 < right ? this.anchor + 7 : right;
const [Y, , ] = this.nowDate();
let tpl = `
${this.lang === "en" ? "Choose a Year" : "選擇年份"}
`; if (this.anchor - 4 > left) { tpl += ""; } else { tpl += "
?
"; } tpl += "
"; for (let i = start; i <= end; i++) { if (i !== Y) { tpl += `${i}`; } else { tpl += `${i}`; } } tpl += "
"; if (this.anchor + 7 < right) { tpl += ""; } else { tpl += "
?
"; }
寫(xiě)在后面

DatePicker比較核心的邏輯就在這里了

400行左右的代碼,每個(gè)人都可以嘗試著寫(xiě)一遍,很有意思的

下一篇文章介紹TimePicker,敬請(qǐng)期待

最后,求star,求fork,求內(nèi)推

https://github.com/veedrin/qing

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/93636.html

相關(guān)文章

  • 徒手UITimePicker

    摘要:是一個(gè)組件庫(kù)目前擁有的組件語(yǔ)法編寫(xiě),無(wú)依賴原生模塊化,以上支持,請(qǐng)開(kāi)啟靜態(tài)服務(wù)器預(yù)覽效果,靜態(tài)服務(wù)器傳送門(mén)采用變量配置樣式辛苦造輪子,歡迎來(lái)倉(cāng)庫(kù)四月份找工作,求內(nèi)推,坐標(biāo)深圳寫(xiě)在前面去年年底項(xiàng)目中嘗試著寫(xiě)過(guò)一個(gè)分頁(yè)的組件,然后就有了寫(xiě)的想法 QingUI是一個(gè)UI組件庫(kù)目前擁有的組件:DatePicker, TimePicker, Paginator, Tree, Cascader, ...

    Codeing_ls 評(píng)論0 收藏0
  • 徒手UIPaginator

    摘要:是一個(gè)組件庫(kù)目前擁有的組件語(yǔ)法編寫(xiě),無(wú)依賴原生模塊化,以上支持,請(qǐng)開(kāi)啟靜態(tài)服務(wù)器預(yù)覽效果,靜態(tài)服務(wù)器傳送門(mén)采用變量配置樣式辛苦造輪子,歡迎來(lái)倉(cāng)庫(kù)四月份找工作,求內(nèi)推,坐標(biāo)深圳寫(xiě)在前面去年年底項(xiàng)目中嘗試著寫(xiě)過(guò)一個(gè)分頁(yè)的組件,然后就有了寫(xiě)的想法 QingUI是一個(gè)UI組件庫(kù)目前擁有的組件:DatePicker, TimePicker, Paginator, Tree, Cascader, ...

    liuhh 評(píng)論0 收藏0
  • 徒手UICascader

    摘要:但是如果一剎那我不想選江疏影了,我想選張雨綺因?yàn)樾卮?,首先我要從霍思燕換到高圓圓,然后轉(zhuǎn)到張雨綺,選中展示出來(lái),這時(shí)候就要先刪除霍思燕,然后把高圓圓和張雨綺進(jìn)來(lái)。 QingUI是一個(gè)UI組件庫(kù)目前擁有的組件:DatePicker, TimePicker, Paginator, Tree, Cascader, Checkbox, Radio, Switch, InputNumber, I...

    junnplus 評(píng)論0 收藏0
  • 徒手UITree

    摘要:是一個(gè)組件庫(kù)目前擁有的組件語(yǔ)法編寫(xiě),無(wú)依賴原生模塊化,以上支持,請(qǐng)開(kāi)啟靜態(tài)服務(wù)器預(yù)覽效果,靜態(tài)服務(wù)器傳送門(mén)采用變量配置樣式辛苦造輪子,歡迎來(lái)倉(cāng)庫(kù)四月份找工作,求內(nèi)推,坐標(biāo)深圳寫(xiě)在前面去年年底項(xiàng)目中嘗試著寫(xiě)過(guò)一個(gè)分頁(yè)的組件,然后就有了寫(xiě)的想法 QingUI是一個(gè)UI組件庫(kù)目前擁有的組件:DatePicker, TimePicker, Paginator, Tree, Cascader, ...

    2i18ns 評(píng)論0 收藏0
  • 徒手框架--高并發(fā)環(huán)境下的請(qǐng)求合并

    摘要:我們就可以將這些請(qǐng)求合并,達(dá)到一定數(shù)量我們統(tǒng)一提交。總結(jié)一個(gè)比較生動(dòng)的例子給大家講解了一些多線程的具體運(yùn)用。學(xué)習(xí)多線程應(yīng)該多思考多動(dòng)手,才會(huì)有比較好的效果。地址徒手?jǐn)]框架系列文章地址徒手?jǐn)]框架實(shí)現(xiàn)徒手?jǐn)]框架實(shí)現(xiàn) 原文地址:https://www.xilidou.com/2018/01/22/merge-request/ 在高并發(fā)系統(tǒng)中,我們經(jīng)常遇到這樣的需求:系統(tǒng)產(chǎn)生大量的請(qǐng)求,但是這...

    劉東 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<