Uniapp微信小程序:自封装自定义插槽下拉选择器|简化使用方法,支持抓取任意字段,数据回显同时预选回显项,支持多种格式的数据源(个人学习记录)
封装组件template view classgeneral-picker-simple slot :showTextsimpleSelectedText :openPickeropenSimplePicker up-button typeinfo tapopenSimplePicker {{ simpleSelectedText }} /up-button /slot /view !-- 配置选择器预选中索引 -- up-picker :showpickerShow :columns[list] confirmhandleConfirm cancelhandleCancel :keyNameshowKey :titletitle :confirmColorconfirmColor :cancelColorcancelColor closehandleClose closeOnClickOverlay :defaultIndex[pickerDefaultIndex] /up-picker /template script setup import { ref, watch, computed, nextTick } from vue; // 组件参数定义 const props defineProps({ list: { type: Array, default: () [] }, title: { type: String, default: 请选择 }, confirmColor: { type: String, default: #1989fa }, cancelColor: { type: String, default: #999 }, showKey: { type: String, default: text }, valueKey: { type: String, default: id }, modelValue: { type: [String, Number], default: }, placeholder: { type: String, default: 请选择 } }); // 事件定义 const emit defineEmits([update:modelValue, select, cancel]); // 内部状态 const pickerShow ref(false); const rawSelectedText ref(); const pickerDefaultIndex ref(0); // 选择器预选中索引 // 自动补占位符的展示文本 const simpleSelectedText computed(() { return rawSelectedText.value || props.placeholder; }); // 更新选中文本 const updateSelectedText (newVal) { if (!newVal || props.list.length 0) { rawSelectedText.value ; pickerDefaultIndex.value 0; return; } // 兼容类型匹配查找选项 const findItem props.list.find(item { if (typeof item string) return item newVal; const itemValue item[props.valueKey] ; const targetValue newVal ; return itemValue targetValue; }); if (findItem) { rawSelectedText.value typeof findItem string ? findItem : (findItem[props.showKey] || ); calcPickerIndex(newVal); } else { rawSelectedText.value ; pickerDefaultIndex.value 0; } }; // 计算选择器预选中索引 const calcPickerIndex (targetValue) { if (!targetValue || props.list.length 0) { pickerDefaultIndex.value 0; return; } const targetIndex props.list.findIndex(item { if (typeof item string) return item targetValue; const itemValue item[props.valueKey] ; const targetVal targetValue ; return itemValue targetVal; }); pickerDefaultIndex.value targetIndex -1 ? targetIndex : 0; }; // 监听选中值变化 watch(() props.modelValue, (newVal) { nextTick(() updateSelectedText(newVal)); }, { immediate: true }); // 监听数据源变化 watch(() props.list, () { if (props.modelValue) nextTick(() updateSelectedText(props.modelValue)); }, { deep: true }); // 打开选择器 const openSimplePicker () { nextTick(() { calcPickerIndex(props.modelValue); pickerShow.value true; }); }; // 确认选择 const handleConfirm (e) { let result { showText: , formValue: }; if (typeof e.value[0] string) { result.showText e.value[0]; result.formValue e.value[0]; } else { result.showText e.value[0][props.showKey] || ; result.formValue e.value[0][props.valueKey] || ; } rawSelectedText.value result.showText; emit(update:modelValue, result.formValue); emit(select, result.formValue, result.showText); pickerShow.value false; }; // 取消/关闭选择器 const handleCancel () { emit(cancel); pickerShow.value false; }; const handleClose () { emit(cancel); pickerShow.value false; }; // 暴露方法 defineExpose({ openSimplePicker }); /script style scoped .general-picker-simple { display: inline-block; } /style示例代码template view classdemo-container !-- 示例1默认按钮 纯文本数组 -- view classdemo-block view classdemo-title 默认按钮模式纯文本数组/view !-- 纯文本数组选择器默认按钮样式 -- GeneralPicker :listtextOptions title请选择文本选项 v-modelselectedTextValue selecthandleTextSelect / view classselected-tip当前选中值{{ selectedTextValue }}/view /view !-- 示例2自定义按钮 对象数组 -- view classdemo-block view classdemo-title 自定义按钮模式对象数组/view !-- 对象数组选择器插槽自定义按钮 -- GeneralPicker :listobjectOptions title请选择对象选项 showKeyname valueKeyid v-modelselectedObjectId selecthandleObjectSelect template #default{ showText, openPicker } view classcustom-select-btn tapopenPicker {{ showText }} /view /template /GeneralPicker view classselected-tip当前选中ID{{ selectedObjectId }}/view /view /view /template script setup import { ref } from vue; import GeneralPicker from /components/GeneralPicker.vue; // 确认组件实际路径 // 数据源定义 // 纯文本数组数据源适用于简单文本选择 const textOptions ref([选项一, 选项二, 选项三]); // 对象数组数据源适用于需要区分展示文本和实际值的场景 const objectOptions ref([{ name: 选项一, id: 1 }, { name: 选项二, id: 2 }, { name: 选项三, id: 3 } ]); // 选中值绑定 // 纯文本数组选中值 const selectedTextValue ref(选项二); // 对象数组选中ID实际业务值 const selectedObjectId ref(2); // 事件处理 /** * 纯文本选择回调 */ const handleTextSelect (value, text) { console.log(纯文本模式选中, { value, text }); }; /** * 对象数组选择回调 */ const handleObjectSelect (id, text) { console.log(自定义按钮模式选中, { id, text }); }; /script style langscss scoped .demo-container { padding: 30rpx; } .demo-block { margin-bottom: 40rpx; padding-bottom: 20rpx; border-bottom: 1px solid #f0f0f0; } .demo-title { font-size: 32rpx; font-weight: bold; margin: 20rpx 0; color: #333; } .selected-tip { margin-top: 10rpx; line-height: 2; color: #666; padding-left: 10rpx; } .custom-select-btn { padding: 20rpx 40rpx; background: #f5f5f5; border-radius: 8rpx; color: #333; display: inline-block; margin: 20rpx 0; :active { background: #e8e8e8; } } /style依赖组件Uview-Plus组件文档https://www.cnblogs.com/zhangyouwu/p/18561086
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2421913.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!