手把手帶你開發一個uni-app日曆外掛(並行布)

2022-06-30 22:01:27
本篇文章手把手帶大家開發一個uni-app日曆外掛,介紹下一款日曆外掛是如何從開發到釋出的,希望對大家有所幫助!

相信我們在開發各類小程式或者H5,甚至APP時,會把uni-app作為一個技術選型,其優點在於一鍵打包多端執行,較為強大的跨平臺的效能。但是,只要開發就免不了使用外掛,所以Dcloud為了方便開發者同時也為注入活力,開放了uni的外掛市場。從此,我們可以很方便的使用其中的一些第三方外掛來滿足我們要開發的一些業務需求了。但你知道怎麼製作一款uni的外掛嗎?它又是如何釋出到外掛商城裡的嗎?

介紹

開發過微信小程式的朋友或許知道,它的主包限制成2M,我們在外掛商城挑選外掛時,其實還是要斟酌的,儘可能使用更輕量級的,使用起來更方便的。最近有個需求,頁面中出現了一個日曆,日曆的功能很簡單就是切換月份,後端一些特殊日期資料能用顏色標記一下即可。但引入的ui庫的日曆又有點大,藉此機會,本期就按照需求特製了一款輕量級的日曆外掛進行分享,看看它是如何開發出來並行布到外掛商城上面去的。

讓我們先來看看釋出使用後的效果吧:

1.gif

開發

建立檔案

我們先開啟 HBuilder X ,建立一個 uni-app 的專案,在裡面建立一個名叫 uni_modules 的資料夾。

2.gif

然後 uni_modules 上點選右鍵,裡面選擇新建 uni_modules外掛 ,然會出現一個彈框要求你對外掛起名。

3.gif

起名其實可以隨意,最好語意化強一些還要帶點自己的特色,比如,這款日曆外掛我起名叫 ml-calendar ,咳咳,大致意思就是 jsmask-light-calendar,也就是jsmask的輕量級日曆,見笑了。就這樣,點選建立,就會生成好一個外掛結構,我們就會在這裡面寫關於這個外掛的所有邏輯。

4.gif

還沒結束,我們還要在裡面建立一個index.js的檔案,裡面寫入:

import mlCalendar from "./components/ml-calendar/ml-calendar"
export default mlCalendar

因為我們只涉及到一個ui元件,所以 export default直接指到這個元件上就好了。這一步很關鍵,因為如果不寫他的話,在參照這款外掛的時候預設是找不到這個外掛的,會報錯查詢失敗。

5.gif

依賴引入

因為本次需要快速開發出一款日曆來,所以免不了出現很多時間形式的判斷和驗證,比如,如果日曆是當天就不會顯示阿拉伯數位了會直接顯示漢字今日,所以生成的時候就要判斷當前系統時間和日期是不是同一天上。所以,為了方便使用了 dayjs ,相信作為前端開發者沒有不知道它的大名吧,它是一款極其輕量的時間庫,當然你也可以自己把用到的手寫出來,這樣體積會更小,但這裡為了方便和更多擴充套件可能就引入進來了。

這裡的 dayjs 檔案 ,為了省事,我是從node安裝後的包裡拷貝出來的:

6.gif

現在就可以在 vue 檔案中引入使用它了,當然,我這裡還建了個libs資料夾專門來儲存第三方庫檔案的。

import dayjs from '../../libs/dayjs.js'

傳入引數

我們先來看看要實現的介面圖:

7.gif

export default {
    name: "ml-calendar",
    props: {
        value: {
            type: [Number, String, Date],
            default: ""
        },
        range: {
            type: Array,
            default: () => ["2021-01", ""]
        },
        rows: {
            type: Array,
            default: () => []
        },
        // ...
    },
    // ...
}

我們需要提前想好可能會傳來什麼值,會影響這個日曆的生成,首先,肯定要知道需要哪年哪月的資料,value 這裡可以傳入多種型別然後再讓dayjs處理出來,得到統一的日期格式,預設傳空字串,意思就是當月。畢竟,知道年份月份才能得到當月的天數生成周對應的日麼。

range 代表時間範圍,可以選擇上圖的左右箭頭對應的上一個月和下一個月,月份不能超出範圍。

rows 代表著你傳入日期對應的標識色,如 :

let rows = [{
    date: "2022-5-21",
    color: "#5F8BFB"
}, {
    date: "2022-5-24",
    color: "#FBA75F"
}, {
    date: "2022-5-26",
    color: "#FBA75F"
}]

接下來,我們就圍繞著這些引數去完成這個日曆編寫。

遍歷日期

export default {
    name: "ml-calendar",
    data() {
        return {
            year: "",
            month: "",
            date: [],
            now: "",
            first: dayjs(this.value).format("YYYY-MM")
        }
    },
    methods: {
        render() {
            this.date.length = 0;
            this.year = dayjs(this.first).year();
            this.month = dayjs(this.first).month() + 1;
            this.now = dayjs().format("YYYY-MM-DD");

            let days = [...new Array(dayjs(this.first).daysInMonth()).keys()].map(i => {
                let n = i + 1;
                let text = n < 10 ? "0" + n : n;
                let date = `${this.first}-${text}`;
                let now = !!(dayjs(date).diff(this.now, 'day') === 0);
                let color = "";
                let obj = this.rows.find(item => dayjs(date).diff(item.date, 'day') === 0);
                if (obj) {
                    color = obj.color
                }
                return {
                    text,
                    date,
                    color,
                    now,
                }
            })
            let week = dayjs(`${this.year}-${this.month}-1`).day();
            this.date = [...new Array(week ? (week - 1) : 6).fill(null), ...days]
        },
        // ...
    }
}

首先,我們定義一個 first 變數,表示需要展示的年月,因為要變成日曆,肯定日期要對應周幾,這樣我們通過 dayjs(this.first).daysInMonth() 方法獲取當前傳入月份的天數,然後進行遍歷,把 rows 傳入的標記色都給填充上。再通過得知算出這個月的第一天是周幾,然後在前面就空出多少個資料來生成出 date

<template>
	<view class="ml-calendar">
        <!-- more -->
		<view class="ml-calendar-month__days">
			<view class="ml-calendar-month__days__day" v-for="(item, index) in date" :key="index"
				:class="{'active':item&&item.color}" @click="$emit('select',item)">
				<view class="ml-calendar-tips" :style="{'background-color':item&&item.color}"></view>
				<text v-if="item" :class="[{'now':item.now}]">{{item.now?'今日':item.text}}</text>
			</view>
		</view>
	</view>
</template>

當然,通過觀察,每行始終是7個等大的格子,所以樣式方面我們大可以使用 grid佈局 ,可以十分快速的實現效果 。

.m-calendar-month__days {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
}

監聽更新

當修改當前日期時,或者標記資料時都要求重新渲染日曆,此時用 watch 就可以輕鬆實現。

watch: {
    first(v) {
        this.render()
        this.$emit("change", {
            year: this.year,
            month: this.month,
        })
    },
    rows(v) {
       this.render()
    }
}

別忘了,我們還要定義兩個事件給開發者使用,在 first 改變是會發出來一個 change事件 ,表示當前日曆的年月,發生了改變發出通知。此時接受到通知,你可以從後端走介面重新獲取新值或者完成其他的業務邏輯。而另一個是 select事件 來完成點選某個日期,發出的響應,在上個步驟的遍歷階段可以看出。

使用測試

<template>
    <view>
        <ml-calendar style="width:100%" :rows="rows" :range="range" :value="value" @change="changeDate" @select="selectDate" />
    </view>
</template>
<script>
export default {
    data() {
        return {
            value:"2022-05",  // 初始化顯示的月份
            range: ["2021-05", ""], // 時間範圍
            rows: [{   // 特殊日期標註資料,當前日期和標註顏色
                date: "2022-5-21",
                color: "#5F8BFB"
            }, {
                date: "2022-5-24",
                color: "#FBA75F"
            }, {
                date: "2022-5-26",
                color: "#FBA75F"
            }],
            // ...
        }
    },
    methods: {
        // 切換日曆時觸發
        changeDate(e){
            console.log(e)  
        },
        // 點選日期返回當前日期物件 
        selectDate(e){
            console.log(e)  
        }
    }
    //...
}
</script>

日曆的大小可能受外界容器的影響,所以,給他加一個100%的寬,此時,我們可以看到,他瀏覽器和微信小程式的表現是基本一致的。

8.gif

釋出

編輯readme

釋出之前我們當然需要在裡面的 readme.md 檔案寫寫你開發這款軟體是什麼?怎麼用?這些至少說明白,不然別人過段時間自己都忘了怎麼用了,方便別人也方便自己吧。

9.gif

執行釋出

最後我們在 uni_modules 的資料夾中,找的我們剛剛寫的 ml-calendar ,在這個資料夾上點選右鍵選擇 釋出到外掛市場 (此前,必須要在Dcloud註冊為開發者並且實名認證)。

此時,會填寫一些關於這款外掛的資訊:

10.gif

當然,裡面會涉及到這款外掛的相容情況的填寫,至於到底兼不相容各端,收不收費根據情況去選擇吧。

11.gif

當點選提交後,就會執行釋出指令了。

此時,如果控制檯會有釋出後的返回資訊:

12.gif

如果成功則會返回一個外掛地址連結,點開連結:

13.gif

到這裡屬於你自己的一款外掛就開發並行布完成了,是不是非常的容易啊。以後在開發uni-app時遇到可以抽離的,我們都可以製成外掛釋出出來,成就感和便利性都是滿滿當當~

推薦:《》

以上就是手把手帶你開發一個uni-app日曆外掛(並行布)的詳細內容,更多請關注TW511.COM其它相關文章!