欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

微信小程序自定義數(shù)據(jù)實(shí)現(xiàn)級聯(lián)省市區(qū)組件功能

 更新時(shí)間:2024年03月22日 11:25:22   作者:水星記_  
這篇文章主要介紹了微信小程序自定義數(shù)據(jù)實(shí)現(xiàn)級聯(lián)省市區(qū)組件功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧

前言

在微信小程序中,官方文檔提供的省市區(qū)組件,可以讓用戶更加方便快捷地選擇省市區(qū),但是官方提供的組件有一個(gè)缺點(diǎn),無法自定義數(shù)據(jù),但如果項(xiàng)目中需要使用自己的數(shù)據(jù),顯然就得尋找其它的組件實(shí)現(xiàn)。

官方組件

優(yōu)點(diǎn)

  • 使用官方組件具有穩(wěn)定性和兼容性,可以保證在不同的微信小程序版本中正常運(yùn)行;
  • 官方組件的使用文檔詳細(xì),易于上手,可以快速實(shí)現(xiàn)級聯(lián)省市區(qū)組件;
  • 官方組件的樣式和交互效果都比較簡潔,符合微信小程序的設(shè)計(jì)風(fēng)格。

缺點(diǎn)

  • 官方組件的樣式和交互效果比較單一,無法滿足一些特殊需求;
  • 官方組件的自定義能力比較有限,無法進(jìn)行個(gè)性化定制。

wxml 文件

<picker mode="region" bindchange="bindRegionChange" value="{{region}}" custom-item="{{customItem}}">
    <view class="picker">
        當(dāng)前選擇:{{region[0]}},{{region[1]}},{{region[2]}}
    </view>
</picker>

js 文件

Page({
  data: {
    region: [],
  },
  bindRegionChange: function (e) {
    console.log('picker發(fā)送選擇改變,攜帶值為', e.detail.value)
    this.setData({
      region: e.detail.value
    })
  }
})

實(shí)現(xiàn)效果

vant-weapp 實(shí)現(xiàn)

vant-weapp 中為我們提供了級聯(lián)選擇器,并且組件的樣式和交互效果比較豐富,可以滿足各種特殊需求,使用這個(gè)組件也可以實(shí)現(xiàn),但是 vant-weapp 也有一個(gè)問題,當(dāng)數(shù)據(jù)量比較大時(shí),組件就會變得異常卡頓。

wxml 文件

<van-field value="{{ fieldValue }}" is-link readonly label="地區(qū)" placeholder="請選擇所在地區(qū)" bind:tap="onClick" />
<van-popup show="{{ show }}" round position="bottom">
    <van-cascader field-names="{{ fieldNames }}" wx:if="{{ show }}" value="{{ cascaderValue }}" title="請選擇所在地區(qū)"
        options="{{ options }}" bind:close="onClose" bind:finish="onFinish" />
</van-popup>

js 文件

Page({
  data: {
    show: false,
    fieldValue: '',
    cascaderValue: '',
    fieldNames: {
      text: 'label',
      value: 'value',
      children: 'children',
    },
    options: [],
  },
  onLoad() {
    this.setData({
      options: JSON.parse(wx.getStorageSync('addressInfo'))
    })
  },
  onClick() {
    this.setData({
      show: true,
    });
  },
  onClose() {
    this.setData({
      show: false,
    });
  },
  onFinish(e) {
    const {
      selectedOptions,
      value
    } = e.detail;
    const fieldValue = selectedOptions
      .map((item) => item.label || item.value)
      .join('/');
    this.setData({
      fieldValue,
      cascaderValue: value,
    })
    console.log(fieldValue);
    this.onClose()
  },
});

實(shí)現(xiàn)效果

肉眼可見非??D,每點(diǎn)擊一次都要等好幾秒才能反應(yīng)過來。

自定義組件

既然上面兩種實(shí)現(xiàn)方法都不符合我們的需求,那么自己自定義組件就可以完全按照自己的需求進(jìn)行設(shè)計(jì)和開發(fā)。

封裝 wxml 文件

<picker mode="multiSelector" model:value="{{pickerValue}}" range-key="label" range="{{range}}" bindchange="onChange"
	bindcolumnchange="columnChange">
	<view>
		<!-- 如果已經(jīng)選擇了選項(xiàng),則顯示選項(xiàng)的label屬性,否則顯示placeholder屬性。 -->
		<text wx:if="{{label}}"> {{ label }} </text>
		<text style="color: #999" wx:else> {{ placeholder }}</text>
	</view>
</picker>

封裝 js 文件

Component({
    properties: {
        // placeholder為選擇器的默認(rèn)提示文字
        placeholder: {
            type: String,
            value: '請選擇',
        },
        // value為選擇器的默認(rèn)值,類型為數(shù)組
        value: {
            type: Array,
            value: [],
            // observer監(jiān)聽value的變化,如果有值則調(diào)用setLabel方法設(shè)置選擇器的label
            observer(selectedValues) {
                if (selectedValues && selectedValues.length) {
                    this.setLabel();
                }
            }
        }
    },
    data: {
        // label為選擇器的顯示值
        label: '',
        // range為選擇器的可選項(xiàng),類型為數(shù)組,包含三個(gè)數(shù)組,分別為省、市、區(qū)/縣
        range: [],
        // pickerValue為選擇器的選中值,類型為數(shù)組,包含三個(gè)數(shù)字,分別為省、市、區(qū)/縣的下標(biāo)
        pickerValue: [],
        // addressList為選擇器的數(shù)據(jù)源,類型為數(shù)組,包含省、市、區(qū)/縣的信息
        addressList: [],
    },
    // attached生命周期函數(shù),在組件實(shí)例進(jìn)入頁面節(jié)點(diǎn)樹時(shí)執(zhí)行
    attached() {
        // 獲取地址列表,如果value為空則初始化range
        this.getAddressList().then(() => {
            if (!this.data.value.length) {
                this.initRange();
            }
        });
    },
    methods: {
        // getAddressItem方法用于將地址信息轉(zhuǎn)換為選擇器可用的格式
        getAddressItem(data) {
            return {
                label: data.label,
                value: data.value
            };
        },
        // setAddressList方法用于將地址列表轉(zhuǎn)換為選擇器可用的格式
        setAddressList(list) {
            return list.map((v) => this.getAddressItem(v));
        },
        // getAddressByCode方法用于根據(jù)value值獲取地址信息及其在數(shù)組中的下標(biāo)
        getAddressByCode(list = [], value) {
            let index = list.findIndex(item => item.value === value);
            return [index, list[index] || {}];
        },
        // openChildren方法用于根據(jù)value值打開下一級選擇器
        openChildren(list, keys) {
            let result = [];
            const handle = (arr, keys) => {
                let newarr = arr.map((v, index) => {
                    if (keys && keys.length) {
                        let [currentKey, ...nextKey] = keys;
                        if (currentKey === index && Array.isArray(v.children)) {
                            handle(v.children, nextKey);
                        }
                    }
                    return this.getAddressItem(v);
                });
                result.push(newarr);
            }
            handle(list, keys);
            return result.reverse();
        },
        // onChange方法為選擇器的change事件處理函數(shù),用于設(shè)置label和觸發(fā)change事件
        onChange(e) {
            let [r1, r2, r3] = this.data.range;
            const [v1, v2, v3] = e.detail.value;
            const selected = [r1[v1], r2[v2], r3[v3]];
            const values = selected.map(v => v.value);
            const label = selected.map(v => v.label).join('-');
            this.setData({
                label
            });
            this.triggerEvent("change", {
                value: values,
                label
            });
        },
        // columnChange方法為選擇器的columnchange事件處理函數(shù),用于設(shè)置range和pickerValue
        columnChange(e) {
            const {
                column,
                value
            } = e.detail;
            this.setColumn(column, value);
        },
        // setColumn方法用于設(shè)置range和pickerValue
        setColumn(column, value) {
            let addressList = this.data.addressList;
            if (!addressList || addressList.length === 0) return;
            let [r1, r2, r3] = this.data.range;
            if (column === 0) {
                r2 = this.setAddressList(addressList[value].children);
                r3 = this.setAddressList(addressList[value].children[0].children);
                this.setData({
                    pickerValue: [value, 0, 0]
                });
            } else if (column === 1) {
                const [v1] = this.data.pickerValue;
                r3 = this.setAddressList(addressList[v1].children[value].children);
                this.setData({
                    pickerValue: [v1, value, 0]
                });
            }
            this.setData({
                range: [r1, r2, r3]
            });
        },
        // setLabel方法用于設(shè)置label
        setLabel() {
            let addressList = this.data.addressList;
            if (addressList && addressList.length) {
                const [v1, v2, v3] = this.data.value;
                const [s1, {
                    label: t1,
                    children: l1
                }] = this.getAddressByCode(addressList, v1);
                const [s2, {
                    label: t2,
                    children: l2
                }] = this.getAddressByCode(l1, v2);
                const [s3, {
                    label: t3
                }] = this.getAddressByCode(l2, v3);
                const label = [t1, t2, t3].filter(v => v).join('-');
                const pickerValue = [s1, s2, s3];
                const range = this.openChildren(addressList, [s1, s2, s3]);
                if (label.length) {
                    this.setData({
                        label,
                        range,
                        pickerValue
                    });
                }
            } else {
                this.getAddressList().then(() => {
                    this.setLabel();
                });
            }
        },
        // initRange方法用于初始化range
        initRange() {
            if (!this.data.value.length) {
                const range = this.openChildren(this.data.addressList, [0, 0, 0]);
                this.setData({
                    range
                });
            }
        },
        // getAddressList方法用于獲取地址列表
        getAddressList() {
            return new Promise((resolve, reject) => {
                wx.getStorage({
                    key: 'addressInfo',
                    success: (res) => {
                        this.setData({
                            addressList: JSON.parse(res.data)
                        });
                        resolve();
                    },
                    fail: (err) => {
                        reject(err);
                    }
                });
            });
        },
    },
});

使用 wxml 文件

<picker-region bindchange="regionChange" placeholder="請選擇所在區(qū)域" value="{{value}}" />

使用 js 文件

Page({
  data: {
    value: ""
  },
  regionChange(e) {
    console.log(e)
  },
})

模擬 json 數(shù)據(jù)格式

[
    {
        "value": "110000",
        "label": "北京市",
        "regionLevel": "1",
        "parentRegionCode": "0",
        "children": [
            {
                "value": "110100",
                "label": "市轄區(qū)",
                "regionLevel": "2",
                "parentRegionCode": "110000",
                "children": [
                    {
                        "value": "110101",
                        "label": "東城區(qū)",
                        "regionLevel": "3",
                        "parentRegionCode": "110100",
                        "children": null
                    },
                    {
                        "value": "110118",
                        "label": "密云區(qū)",
                        "regionLevel": "3",
                        "parentRegionCode": "110100",
                        "children": null
                    }
                ]
            }
        ]
    },
    {
        "value": "120000",
        "label": "天津市",
        "regionLevel": "1",
        "parentRegionCode": "0",
        "children": [
            {
                "value": "120100",
                "label": "市轄區(qū)",
                "regionLevel": "2",
                "parentRegionCode": "120000",
                "children": [
                    {
                        "value": "120101",
                        "label": "和平區(qū)",
                        "regionLevel": "3",
                        "parentRegionCode": "120100",
                        "children": null
                    },
                    {
                        "value": "120102",
                        "label": "河?xùn)|區(qū)",
                        "regionLevel": "3",
                        "parentRegionCode": "120100",
                        "children": null
                    }
                ]
            }
        ]
    }
]

實(shí)現(xiàn)效果

到此這篇關(guān)于微信小程序自定義數(shù)據(jù)實(shí)現(xiàn)級聯(lián)省市區(qū)組件的文章就介紹到這了,更多相關(guān)小程序級聯(lián)省市區(qū)組件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論