Initial commit

This commit is contained in:
lnljyang
2025-12-30 09:44:46 +08:00
commit 82b8d21506
147 changed files with 39113 additions and 0 deletions

View File

@@ -0,0 +1,293 @@
<template>
<view class="popup" v-show="show">
<view class="bg" @tap="cancelMultiple"></view>
<view class="selectMultiple" :animation="animationData">
<view class="multipleBody">
<view class="title">
<view class="close" @tap="cancelMultiple">
取消
</view>
<view class="name">
<!-- cancelButton="none" 不展示取消按钮-->
<uni-search-bar @input="updateList" cancelButton="none">
</uni-search-bar>
</view>
<view class="confirm" @tap="confirmMultiple">
确认
</view>
</view>
<view class="list">
<view class="mask mask-top"></view>
<view class="mask mask-bottom"></view>
<scroll-view class="diet-list" scroll-y="true">
<view v-for="(item, index) in list" :class="['item', item.selected ? 'checked' : '']" @tap="onChange(index, item)">
<span style="font-size: 16px;">{{item.label}}</span>
<view class="icon" v-show="item.selected">
<icon type="success_no_circle" size="16" color="#2D8DFF"/>
</view>
</view>
</scroll-view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name:"curry-multi-select",
data() {
return {
// 选中值
value: [],
// 选中列表
selected: [],
// 列表数据
list: [],
originList: [],
// 出场动画
animationData: {},
};
},
props: {
// 是否显示
show: {
type: Boolean,
default: false
},
// 标题
title: {
type: String,
default: ''
},
//数据列表
columns: {
type: Array,
default: []
},
// 默认选中
defaultIndex: {
type: Array,
default: [],
},
isMultiSelect: {
type: Boolean,
default: true
},
},
watch: {
// 监听是否显示
show(val) {
if(val) {
this.openMultiple();
}
}
},
methods: {
updateList(str){
this.list.map(e => {
this.originList.map(item => {
if (e.selected && item.value === e.value) {
item.selected = true
}
})
})
// 需要将 list 中已被选取的更新到 originList 中,否则会有选完部分在搜索其他部分选会清空之前选的 bug
if (str === null || str === undefined || str === '') {
this.list = JSON.parse(JSON.stringify(this.originList))
} else {
// 筛选时已经选取的需要存放到list中
this.list = this.originList.filter(e => e.label.indexOf(str) > -1 || e.selected);
}
},
// 列点击事件
onChange(index, item) {
// 单选
if (!this.isMultiSelect) {
this.value = [];
this.selected = [];
this.value.push(item.value.toString());
this.selected.push({
label: item.label,
value: item.value,
});
return this.$emit("confirm", {selected: this.selected, value: this.value});
}
// 是否已选中
if(this.value.indexOf(item.value.toString()) >= 0) {
this.list[index].selected = false;
} else {
this.list[index].selected = true;
}
// 筛选已勾选数据
this.value = [];
this.selected = [];
this.list.forEach((col_item, col_index) => {
if(col_item.selected) {
this.value.push(col_item.value.toString());
this.selected.push({
label: col_item.label,
value: col_item.value,
});
}
});
this.$emit("change", {selected: this.selected, value: this.value});
},
// 弹出框开启触发事件
openMultiple() {
// 初始化列表数据,默认勾选数据
this.value = this.defaultIndex;
this.columns.forEach((item, index) => {
this.$set(item, "selected", false);
if(this.value.indexOf(item.value.toString()) >= 0) {
item.selected = true;
}
});
this.originList = Object.assign([], this.columns);
this.list = JSON.parse(JSON.stringify(this.originList))
// 弹出动画
this.openAnimation();
},
// 确认
confirmMultiple() {
this.$emit("confirm", {selected: this.selected, value: this.value});
},
// 关闭/取消
cancelMultiple() {
this.$emit("cancel");
},
// 展开动画
openAnimation() {
var animation = uni.createAnimation()
animation.translate(0, 300).step({ duration: 0 });
this.animationData = animation.export();
this.$nextTick(() => {
animation.translate(0, 0).step({ duration: 300, timingFunction: 'ease' });
this.animationData = animation.export()
})
},
}
}
</script>
<style scoped lang="scss">
.popup {
width: 100%;
height: 100vh;
position: fixed;
z-index: 99999;
left: 0;
bottom: 0;
.bg {
width: 100%;
height: 100%;
background-color: rgba(black, .5);
}
}
.selectMultiple {
width: 100%;
position: absolute;
left: 0;
bottom: 0;
background-color: white;
.multipleBody {
width: 100%;
padding: 30rpx;
box-sizing: border-box;
padding-bottom: 80rpx;
.title {
font-size: 28rpx;
display: flex;
flex-direction: row;
align-items: center; /* 添加这一行 */
.close {
width: 80rpx;
text-align: left;
opacity: .5;
}
.name {
width: 530rpx;
text-align: center;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient:vertical;
-webkit-line-clamp:1;
}
.confirm {
width: 80rpx;
text-align: right;
color: #2D8DFF;
}
}
.list {
width: 100%;
padding-top: 30rpx;
position: relative;
.mask {
width: 100%;
height: 120rpx;
position: absolute;
left: 0;
z-index: 2;
pointer-events: none;
&.mask-top {
top: 30rpx;
background-image: linear-gradient(to bottom, #fff, rgba(#fff, 0));
}
&.mask-bottom {
bottom: 0;
background-image: linear-gradient(to bottom, rgba(#fff, 0), #fff);
}
}
.diet-list {
max-height: 600rpx;
}
.item {
position: relative;
width: 100%;
line-height: 40rpx;
border-bottom: 1px solid rgba($color: #000000, $alpha: .05);
padding: 20rpx 0;// 多选框内边距
font-size: 30rpx;
box-sizing: border-box;
text-align: center;
span {
overflow: hidden;
display: -webkit-box;
-webkit-box-orient:vertical;
-webkit-line-clamp:1;
padding: 0 40rpx;
}
.icon {
position: absolute;
right: 10rpx;
top: 50%;
transform: translateY(-50%);
height: 16px;
}
&.checked {
color: #2D8DFF;
}
&:last-child {
border-bottom: none;
margin-bottom: 60rpx;
}
&:first-child {
margin-top: 60rpx;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,29 @@
{
"id": "curry-multi-select",
"name": "下拉多选组件(支持可搜索并兼容单选)",
"displayName": "下拉多选组件(支持可搜索、一键清除并兼容单选)",
"version": "V1.0.0",
"description": "uni-app下拉框: 支持可搜索、多选、单选、一键清除、异步数据响应式更新. 简单好用无bug(有问题评论)(借鉴的: multiple-picker 在其基础上优化了一下)",
"keywords": [
"uni-app下拉多选",
"可搜索",
"一键清除",
"多选组件"
],
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"contact": {
"qq": ""
},
"declaration": {
"ads": "无 ",
"data": "无",
"permissions": "无"
},
"npmurl": ""
},
"repository": "https://gitee.com/huhuyy/plugins-demo.git"
}