前情提要:在做uni小程序时需要做省市的下拉选择。官网有提供省市区的下拉选择。但是这里我不需要区县。所以只能走自定义组件了。第二个就是多列数值范围的下拉。比如,我想选择范围50至100之间的,当第一列选择53的时候,第二列的数值只能选择比第一列大的数值。所以,基于以上两个原因,需要自定义两个组件。

 1.uni官网案例

官网提供四种常用picker下拉用例,而我们的两个组件就是基于这些示例来的。

 2.组件使用效果展示图

tips:这里有个注意事项,因为我这是做的范围筛选,除了固定范围之外,还有个“不限”。誉为包含所有。因为这是一个择偶标准页面。所以业务需求是很明了的。不需要的在代码对应位置自行修改就行

 3.省市组件

        这里的selectShow是控制回显的,这里我没咋用到,所以直接传的一个空数组。除此之外不用传入任何其他参数。组件内引入省市数据即可。省市的json文件自行网上寻找,将省市json修改成下面提供的格式和字段名。然后就可以直接使用组件了。父组件监听cityChange方法,返回的是["省","市"]的数组。

<template>
  <div class="uni-city-picker">
    <picker
      @change="cityChange"
      @columnchange="columnChange"
      mode="multiSelector"
      :value="cityIndex"
      :range="citys"
    >
      <!-- 预留的插槽 -->
      <slot></slot>
    </picker>
  </div>
</template>
 
<script>
import cityJson from '@/utils/city.json'
export default {
  props: {
    selectShow: {
      type: Array,
      default: []
    }
  },
  data() {
    return {
      citys: [[], []],
      cityIndex: [], // 默认
      cityJson: []
    }
  },
  mounted() {
    // 省份
    this.citys[0] = cityJson.map(item => {
      return item.text
    })
 
    // 首先判断需不需要回显
    if (this.selectShow.length > 0) {
      this.cityIndex[0] = (this.citys[0] || []).findIndex(pr => pr == this.selectShow[0]) || 0
      this.cityIndex[1] = (this.citys[1] || []).findIndex(ci => ci == this.selectShow[1]) || 0
    } else {
      this.cityIndex = [0, 0]
    }
    // 省份对应的城市
    this.citys[1] = cityJson
      .filter(item => {
        return item.text == this.selectShow[0] ? this.selectShow[0] : '北京市'
      })
      [this.cityIndex[0]].City.map(child => {
        return child.text
      })
  },
  methods: {
    cityChange(e) {
      // 值改变了
      const index1 = e.detail.value[0] ? e.detail.value[0] : 0
      const index2 = e.detail.value[1] ? e.detail.value[1] : 0
      console.log(e.detail)
	  var city=[];
	  if(cityJson[index1].text!=cityJson[index1].City[index2].text){
		   city = [cityJson[index1].text, cityJson[index1].City[index2].text]
	  }else{
		   city = [cityJson[index1].text]
	  }
      
 
      this.$emit('cityChange', city)
    },
    columnChange(e) {
      console.log('触发列值改变', e)
      //列值改变
      const index = e.detail.value
      if (e.detail.column === 0) {
        var citys = [...this.citys]
        citys[1] = []
        cityJson[index].City.forEach(child => {
          citys[1].push(child.text)
        })
        this.citys = citys
      }
    }
  }
}
</script>
 
<style scoped></style>

 省市的json文件数据结构如下:

 

4.数值范围组件

        组件传入的参数是一个数值数组numarr,做了两个特殊处理,第一列选择“不限”时,第二列则不显示不做选择,第一列选择数值时,第二列的可选值都是大于第一列的。返回值是长度为2的两个数值数组,列如:[20,25]

<template>
  <div class="uni-city-picker">
    <picker
      @change="numChange"
      @columnchange="columnChange"
      mode="multiSelector"
      :value="numIndex"
      :range="number"
    >
      <!-- 预留的插槽 -->
      <slot></slot>
    </picker>
  </div>
</template>
 
<script>
export default {
  name:'number',
  props: {
    numarr: {
      type: Array,
      default: []
    }
  },
  data() {
    return {
      number: [[], []],
      numIndex: [], // 默认
    }
  },
  mounted() {
	this.numarr.unshift("不限");
    this.number=[this.numarr,[]];
  },
  methods: {
    numChange(e) {
	  const index1 = e.detail.value[0] ? e.detail.value[0] : 0
	  const index2 = e.detail.value[1] ? e.detail.value[1] : 0
	  var result=[this.number[0][index1],this.number[1][index2]]
      this.$emit('numChange', result);
    },
    columnChange(e) {
      console.log('触发列值改变', e);
	  //列值改变
	  const index = e.detail.value
	  if (e.detail.column === 0 && e.detail.value!=0) {
	    var arr = this.numarr.slice(e.detail.value,this.numarr.length);
		this.number=[this.numarr,arr];
	  }else if(e.detail.column === 0 && e.detail.value==0){
		this.number=[this.numarr,[]];  
	  }
    }
  }
}
</script>
 
<style scoped></style>

4.使用方式及注意事项

在页面中引入并注册组件。

import selectarea from '@/components/select/selectArea.vue';   //选择省市组件
import selectnum from '@/components/select/selectNum.vue';   //选择数值范围组件

......
data:{
    return{
        ......
        selectShow: [], // 回显时格式  ['省','市'],例如 ['浙江省','杭州市'],
        agearr:[],  //年龄
    }
}
onLoad: function(options) {
	var arr = Array.from({length:200}, (v,k) => k);
	this.agearr = arr.slice(18,100);

},
components: {
	selectarea,
	selectnum
},

......

// 选择城市
cityChange(val) {
	console.log('选择城市val', val)
	this.standard.city = val.join('-')
},

//年龄范围
ageChange(e){
	console.log("年龄:",e);
	if(e[1]){
		this.standard.ageMin=e[0];
		this.standard.ageMax=e[1];
	}else{
		this.standard.ageMin='';
		this.standard.ageMax='';
	}
},

       

<selectarea ref="selectcityRef" @cityChange="cityChange" :selectShow="selectShow">
	<view class="action">
	        {{standard.city?standard.city:'不限'}}
	 </view>
</selectarea>

<selectnum ref="selectageRef" @numChange="ageChange" :numarr="agearr">
		<view class="action">
			{{standard.ageMax?standard.ageMin+'~'+standard.ageMax:"不限"}}
		</view>
</selectnum>

码字不易,转载请注明出处!谢谢

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐