uni-data-picker组件的使用

版本:"version": "2.0.0",

uniapp提供的级联选择的组件。通常用于单列、多列级联选择器,常用于省市区城市选择、公司部门选择、多级分类等场景。

但在使用的时候还是遇到很多问题。这里就记录一下本人在使用2.0.0版本的uni-data-picker组件遇到的问题,以及个性化需求的实现方案。

问题1、数据从属级别错乱问题

预期希望是这样的:

实际现象如下:

显然不正确,数据已经错乱了。但是我们就是按照官网一样写法绑定了localdata,字段名称也是text,value,children了呀。为什么呢?

后来看了组件源码,好像是由于selectIndex导致。是由于接口返回的数据的id值存在重复的,导致会把id相同的数据全部查出来显示。如下:

同时也去问了官方技术人员,得到确切反馈说2.0.0版本的value值(也就是我们那个接口返回的id值)要唯一的,不能存在重复。

解决方案:

方案1: 如果返回的数据结构的id值可以改变的话,可以让后端修改之后返回。然后把id值给组件所需的value属性。

方案2:如果id值已经不能改变了,那就前端对数据进行处理,自己造一个唯一的值赋值给组件所需的value属性。

!注意: 这两种方案只能解决数据层级结构乱的问题,并不能解决标题动态展示的问题。

我的情况是第二种,值不能变,就自己处理数据。

把确保value属性值是唯一即可。

	function formatData(data, level) {
		level = level + 1
		let result = []
		if (!data.length) return []
		result = data.map((item, index) => {
			console.log(_id, index, level)
			let obj = {
				...item,
				text: item.label,
				value: _id++, // 仅仅用于唯一标识数据作用的,解决value值重复问题
				level: level, // 标识当前属于第几个层级
				children: item.children && item.children.length > 0 ? formatData(item.children, level) : []
			}
			return obj
		})
		return result
	}

至此,解决数据错乱问题。

!注意:

uni-data-picker组件得到的值是绑定的每一项数据的value属性的值。 如果需要拿到原本数据的id值的话,可以在处理数据时,把原有的id值拼接上。

	function formatData(data, level) {
		level = level + 1
		let result = []
		if (!data.length) return []
		result = data.map((item, index) => {
			let obj = {
				...item,
				text: item.label,
				value: item.id + '-' + _id++, // 仅仅用于唯一标识数据作用的,解决value值重复问题
				level: level, // 标识当前属于第几个层级
				children: item.children && item.children.length > 0 ? formatData(item.children, level) : []
			}
			return obj
		})
		return result
	}
value: item.id + '-' + _id++,  这样拼接上之后,后期需要数据的时候,可以从这里获取。

问题2、当前选项的标题提示需求的实现

这是我们需求的实现。这些数据不像省市县那种,即便不用标注当前选择的是什么,也能通过显示的值可以知道。

但类似这些版本,系统版本,框架版本之类数据只有一个版本号。如果不熟悉的用户的话,根本不知道当前选择的是什么数据。因此给用户一个提示是非常必要的。

希望如下显示:

组件自身的局限性

这个版本的组件并没有提供可以动态修改当前选择项的标题。已经写死是”请选择“。

所以想要实现动态的话,只能修改源码了。但需要理清楚这个组件的逻辑,在修改,可能需要花一点时间。那有没有其他方案可以替代呢?

我们可以从pupTitle属性入手。可以利用弹框标题提示。如下

实现步骤

1、模板

<uni-data-picker 
  :localdata="publicImgList" 
  v-model="goodInfo.image_id"
  placeholder="请选择镜像" 
  :popup-title="pupTitle"  
  @nodeclick="handleNodeClick">
</uni-data-picker>

2、获取数据

const publicImgList = ref([])
let _id = 0
let level = 0 // 记录当前是第几层
let pupTitle = ref('框架类型')
async function getPublicImgList() {
		const res = await getPublicImageListApi()
		if (res.code === 0) {
			publicImgList.value = formatData(res.data, level) // 加工数据
		}
	}

3、加工数据

function formatData(data, level) {
		level = level + 1
		let result = []
		if (!data.length) return []
		result = data.map((item, index) => {
			let obj = {
				...item,
				text: item.label,
				value: _id++, // 仅仅用于唯一标识数据作用的,解决value值重复问题
				level: level, // 标识当前属于第几个层级
				children: item.children && item.children.length > 0 ? formatData(item.children, level) : []
			}
			return obj
		})
		return result
	}

重要属性:level

用于记录当前的对象数据是属于第几层的数据。

经过处理后,我们就通过level属性知道第几层的数据了。

4、修改puptitle值

注意:

@nodeclick 事件得到的值是当前点击的节点的数据。我们需要去修改它下一级即将要选择什么的标题。

因此e.level是当前点击的层级。

pupTitle的值是下一级需要显示的标题

	function handleNodeClick(e) {
		console.log('当前是第几层:', e.level)
		switch (e.level) {
			case 0:
				pupTitle.value = '框架版本';
				break;
			case 1:
				pupTitle.value = '框架版本';
				break;
			case 2:
				pupTitle.value = 'python版本';
				break;
			case 3:
				pupTitle.value = 'cuda版本';
				break;
			default:
				pupTitle.value = '请选择';
				break;
		}
	}

至此,我们就可以实现我们的需求了。

完整代码

<template>
  <uni-data-picker 
    :localdata="goodInfo.image_type===1?publicImgList:userImgList"
    v-model="goodInfo.image_id" 
   placeholder="请选择镜像" 
   :popup-title="pupTitle"  
   @nodeclick="handleNodeClick"
 >
 </uni-data-picker>
</template>

<script setup>
	import {onLoad} from '@dcloudio/uni-app'
	import {ref} from 'vue'
	import {getPublicImageListApi} from '@/api/product.js'

	onLoad(async (options) => {
		uni.showLoading({
			title:'loading...',
		})
		await Promise.all([getPublicImgList()])
		uni.hideLoading()
	})

	const publicImgList = ref([])
	let _id = 0
	let level = 0
	let pupTitle = ref('框架类型')


	// 格式化数据
	function formatData(data, level) {
		level = level + 1
		let result = []
		if (!data.length) return []
		result = data.map((item, index) => {
			console.log(_id, index, level)
			let obj = {
				...item,
				text: item.label,
				value: _id++, // 仅仅用于唯一标识数据作用的,解决value值重复问题
				level: level, // 标识当前属于第几个层级
				children: item.children && item.children.length > 0 ?formatData(item.children, level) : []
			}
			return obj
		})
		return result
	}


	// 获取系统镜像
	async function getPublicImgList() {
		const res = await getPublicImageListApi()
		if (res.code === 0) {
			publicImgList.value = formatData(res.data, level)
		}
	}


   // 节点点击事件
	function handleNodeClick(e) {
		console.log('当前是第几层:', e.level)
		switch (e.level) {
			case 0:
				pupTitle.value = '框架版本';
				break;
			case 1:
				pupTitle.value = '框架版本';
				break;
			case 2:
				pupTitle.value = 'python版本';
				break;
			case 3:
				pupTitle.value = 'cuda版本';
				break;
			default:
				pupTitle.value = '请选择';
				break;
		}

</script>

最后,这里仅仅记录本次2.0.0版本的uni-data-picker组件遇到的问题。 希望能对大家有帮助~

如果有错误地方或者可以补充的地方,欢迎大家留言。

uni-data-pickeruni-app 框架中的一个日期选择器组件,可以用于选择日期、时间等。下面是一个使用 uni-data-picker 的示例代码: ```html <template> <view> <!-- 点击按钮弹出日期选择器 --> <button @click="showPicker = true">选择日期</button> <!-- uni-data-picker 组件 --> <uni-data-picker v-model="showPicker" :fields="fields" :start="startDate" :end="endDate" @change="onDateChange" ></uni-data-picker> </view> </template> <script> export default { data() { return { showPicker: false, // 是否显示日期选择器 fields: "day", // 可选值为 year、month、day、hour、minute startDate: "2021-01-01", endDate: "2022-12-31", selectedDate: "" // 选中的日期 }; }, methods: { onDateChange(e) { this.selectedDate = e.detail.value; console.log("选中的日期为:", this.selectedDate); } } }; </script> ``` 在上述代码中,我们首先定义了一个按钮,当用户点击该按钮时,会弹出日期选择器。日期选择器使用uni-data-picker 组件,其中 `v-model` 属性用于控制日期选择器的显示和隐藏,`fields` 属性用于设置可选的日期粒度,`start` 和 `end` 属性用于设置可选的日期范围。当用户选择日期时,会触发 `change` 事件,我们可以在事件处理函数中获取选中的日期。 需要注意的是,uni-data-picker 只能在 H5 和 APP使用,不支持在小程序端使用。如果需要在小程序端使用日期选择器,可以使用原生的 `<picker>` 组件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值