微信小程序 封裝一個簡單的彈出滾動選擇器組件

在開發(fā)中,小程序提供了內(nèi)置picker組件來供開發(fā)者使用。但picker組件無法自定義按鈕顏色、選擇器樣式,造成在有UI要求時束手無策(我覺得滑動體驗也不是很好orz)。這個時候就需要使用picker-view組件來自定義彈出滾動選擇器了。
樣式如下:

彈出樣式
首先確定組件的屬性

加入pickerShow是因為項目中有需要觸發(fā)選擇器彈出的需求

  • picker-show 【Boolean】控制彈出隱藏
  • range 【二維Array】 二維數(shù)組,長度表示多少列,數(shù)組的每項表示每列的數(shù)據(jù)
  • title 【Array】 選擇器每列標(biāo)題
  • value 【Array】 value 每一項的值表示選擇了 range 對應(yīng)項中的第幾個(下標(biāo)從 0 開始)
  • is-shadow 【Boolean】 是否需要顯示遮罩層
  • bindchange 【EventHandle】 value 改變時觸發(fā) change 事件 event.detail = value
  • bindfinish 【EventHandle】 完成時觸發(fā) event.detail = value
  • bindcancel 【EventHandle】 取消時觸發(fā)

需要有幾列,就在 range 中傳入幾項

// 使用時,可插入選擇器標(biāo)題
<my-picker range="{{val}}" title="{{['標(biāo)題1','標(biāo)題2']}}" bindfinish="finishHandler" is-shadow="{{true}}">
    <text>從底部彈起的滾動選擇器</text>
</my-picker>
// 頁面邏輯
Page({
    data: {
        val: [// 數(shù)據(jù)列表
            ['大天狗', '玉藻前', '妖刀姬', '茨木童子'],
            ['追月神', '姑獲鳥', '犬神', '黑童子']
        ]
    },
    finishHandler(e){
        console.log(e.detail)// 選擇的結(jié)果 如:["妖刀姬", "犬神"]
    }
})
// .json
{
    "usingComponents": {
        "my-picker": "/components/my-picker/my-picker"
    }
}

如有需要定制樣式,就可以直接在components組件中直接修改就可以啦~

下面是組件的完整代碼
// my-picker.js
Component({
    /**
     * 組件的屬性列表
     */
    properties: {
        pickerShow:{
            type: Boolean, // 類型(必填),目前接受的類型包括:String, Number, Boolean, Object, Array, null(表示任意類型)
            value: false, // 屬性初始值(可選),如果未指定則會根據(jù)類型選擇一個
            observer (newVal, oldVal, changedPath) {
                // 屬性被改變時執(zhí)行的函數(shù)(可選),也可以寫成在methods段中定義的方法名字符串, 如:'_propertyChange'
                // 通常 newVal 就是新設(shè)置的數(shù)據(jù), oldVal 是舊數(shù)據(jù)
            }
        },
        isShadow: {
            type: Boolean,
            value: true,
            observer(newVal, oldVal, changedPath) {}
        },
        range:{
            type: Array,
            value: []
        }, 
        title:{
            type: Array,
            value: []
        },
        value: {// picker-view 內(nèi)的 picker-view-column 當(dāng)前選擇的是第幾項
            type: Array,
            value: [2, 2]
        }
    },
    /**
     * 組件的方法列表
     */
    methods: {
        pickerHandler() {// 控制彈出層顯示隱藏
            this.setData({ pickerShow: !this.data.pickerShow })
        },
        bindChange(e) {// value 改變時觸發(fā) change 事件
            const val = e.detail.value
            this.setData({ value: val })
            let arr = []
            this.data.range.forEach((v, i) => {
                arr.push(v[this.data.value[i]])
            })
            this.triggerEvent('change', arr, {})
        },
        pickerFinish() {// 滾動選擇器 - 完成
            let arr = []
            this.data.range.forEach((v, i) => {
                arr.push(v[this.data.value[i]])
            })
            this.pickerHandler()
            this.triggerEvent('finish', arr, {})
        },
        pickerCancel() {// 滾動選擇器 - 取消
            this.pickerHandler()
            this.triggerEvent('cancel', arr, {})
        }
    }
})
// my-picker.wxml
<view>
    <button bindtap='pickerHandler'>從底部彈起的滾動選擇器</button>

    <view class='com-picker-view {{pickerShow}}'>
        <view class='com-picker-title'>
            <view class='com-picker-cancel' bindtap='pickerCancel'>取消</view>
            <view class='com-picker-result'><slot></slot></view>
            <view class='com-picker-finish' bindtap='pickerFinish'>完成</view>
        </view>
        <view class='com-title' wx:if="{{propTitle.length!=0}}">
            <view wx:for="{{title}}" wx:key="{{index}}">{{item}}</view>
        </view>
        <picker-view indicator-style="height: 40px;" style="width: 100%; height: 200px;" value="{{value}}" bindchange="bindChange">
            <picker-view-column  wx:for="{{range}}" wx:key="{{index}}">
                <view wx:for="{{item}}" wx:for-item="a" style="line-height: 40px">{{a}}</view>
            </picker-view-column>
        </picker-view>
    </view>

    <view class='com-picker-shadow {{pickerShow}}' bindtap='pickerHandler' wx:if="{{isShadow}}"></view> 

</view>
/*my-picker.wxss*/
picker-view-column{font-size: 14px;text-align: center;}
.com-picker-view{position: fixed;bottom: 0;width: 100%;z-index: 3;background: #fff;}

/* 彈出標(biāo)題 */
.com-picker-title{display: flex;padding: 10px 15px;font-size: 14px;border-bottom: #f8f8f8 1px solid;}
.com-picker-cancel{color: #999;}
.com-picker-finish{color: palevioletred;}
.com-picker-result{flex: 1;text-align: center;color: #999;}
.com-title{display: flex;border-bottom: #f8f8f8 1px solid;}
.com-title > view{flex:1;text-align: center;line-height: 40px;font-size: 14px;}

/* 彈出效果 */
.com-picker-view.false{transform:translateY(100%);-webkit-transform:translateY(100%);transition: all .3s cubic-bezier(0,.54,.51,.99);-webikit-transition: all .3s cubic-bezier(0,.54,.51,.99);opacity: 1;}
.com-picker-view.true{transform:translateY(0%);-webkit-transform:translateY(0%);transition: all .3s cubic-bezier(0,.54,.51,.99);-webikit-transition: all .3s cubic-bezier(0,.54,.51,.99);opacity: 1;}

/* 遮罩 */
.com-picker-shadow{width: 100%;height: 100%;position: fixed;top: 0;left: 0; background-color:rgba(0,0,0,0.3);z-index: 2}
.com-picker-shadow.true{ -webkit-transition: opacity 0.35s, visibility 0.35s;transition: opacity 0.35s, visibility 0.35s;visibility: visible;opacity: 1;}
.com-picker-shadow.false{visibility: hidden;opacity: 0;  -webkit-transition: opacity 0.35s, visibility 0.35s;transition: opacity 0.35s, visibility 0.35s;}
// my-picker.json
{
  "component": true,
  "usingComponents": {}
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,316評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,481評論 3 415
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,241評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,939評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,697評論 6 409
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,182評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,247評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,406評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,933評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,772評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,973評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,516評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,638評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,866評論 1 285
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,644評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,953評論 2 373

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