近期一直在做uniapp,所以自己封装了几个组件,是在uniapp提供组件的基础上进行的二次封装,感觉还是挺实用的,先贴个弹出框的,上代码:
/**
* 弹窗组件 made by jidzh
*
* 最后修改时间:2021-03-18
*
* 传入参数:
* filterArray:循环数组
* title:标题
* mode:单选(single)、多选(multiple),默认值为single
* backgroundColor:背景颜色(可传入主题),默认值为#fff
* width:弹出框宽度,默认值为300px
* popPosition:弹出框位置,默认值为right
* currentName:当前选中(single),多选时直接操控multipleIndexes插入选中index
*
* 抛出方法:
* filterChange:选择后返回选择filterArray下标
*
*/
<template>
<uni-drawer :visible="true" ref="draw" :mode="popPosition" :width="width" @change="changeDrawer">
<view class="filterUl">
<view class="popHeader" style=" border-bottom: 1px solid #e3e3e5; ">
<uni-icons type="closeempty" size="26" :color="themeColor" @click="close" />
<text class="title">{{title}}</text>
</view>
<scroll-view scroll-y="true" class="filterBox" :style="{height: mode === 'multiple'?'calc(100% - 91px)':'calc(100% - 51px)'}">
<view class="filterItem">
<view class="filterList" v-for="(item,index) in filterArray" :key="index" @click="mode == 'single'?filterChange(index):mulFilterChange(index)">
{{item}}
<uni-icons v-if="index == multipleIndexes[index] && !$scopedSlots.icon" type="checkmarkempty" :color="themeColor" size="20" style="float:right;"></uni-icons>
<slot name="icon" :icon="index"></slot>
</view>
</view>
</scroll-view>
<view class="filterButton" v-if="mode != 'single'">
<button type="default" class="button giveup" @click="close">取消</button>
<button type="primary" class="button" :style="{'backgroundColor':backgroundColor}" @click="confirm">确定</button>
</view>
</view>
</uni-drawer>
</template>
<script>
import {uniDrawer} from '@dcloudio/uni-ui'
export default {
props:{
filterArray: {
type: Array,
default: () => []
},
mode: {
type: String,
default: 'single'
},
backgroundColor: {
type: String,
default: '#fff'
},
width: {
type: String,
default: '300px'
},
popPosition:{
type: String,
default: 'right'
},
title:{
type: String,
default: ''
},
currentName:{
type: String||Number,
default: ''
}
},
data() {
return {
multiple: [],
multipleIndexes: []
}
},
watch:{
currentName:{
handler: function(val,old){
this.multipleIndexes = [];
let index = this.filterArray?.findIndex((item,index) => item == val);
this.$set(this.multipleIndexes, index, index)
},
immediate:true
}
},
methods: {
// 打开弹窗
open(){
this.$refs.draw.open();
},
changeDrawer(data){
if(!data) if(this.mode === 'multiple') this.confirm();
},
// 关闭弹窗
close(){
this.$refs.draw.close();
},
filterChange: _.debounce(function(index) {
if(this.currentName == this.filterArray[index]) return
this.multipleIndexes = [];
this.$set(this.multipleIndexes, index, index)
this.$emit('filterChange',index);
}, 200),
// 多选,将选中项的index存于multiple
mulFilterChange(index){
this.multipleIndexes[index] == null ? this.$set(this.multipleIndexes, index, index) : this.$set(this.multipleIndexes, index, null)
},
// 确定,点击后返回index数组
confirm(){
this.$emit('filterChange', this.multipleIndexes);
this.$refs.draw.close();
}
}
}
</script>
<style lang="scss">
.filterUl{
width: 100%;
height: 100%;
background-color: color(bg);
.popHeader {
height: 100rpx;
line-height: 100rpx;
padding: 0 16rpx;
border-bottom: 2rpx solid color(bd);
.title {
font-size: 40rpx;
font-weight: 700;
color: color(th);
margin-left: 32rpx;
}
::v-deep .uni-icons{
vertical-align: sub;
}
}
.filterBox{
width: 100%;
height: calc(100% - 91px);
overflow: auto;
display: flex;
flex-direction: column;
.filterItem{
flex: 1;
width: 100%;
.filterList{
height: 92rpx;
text-align: start;
padding: 0 16px;
line-height: 92rpx;
box-sizing: border-box;
border-bottom: 2rpx solid color(bg);
background-color: #fff;
@include radius(mini);
color: color(tb);
margin: 8px 16px;
}
}
}
.filterButton{
width: 100%;
height: 80rpx;
line-height: 80rpx;
.button{
height: 56rpx;
@include font(28);
@include radius(large);
padding: 0;
line-height: 56rpx;
margin-left: 16px;
float: right;
width: 30%;
margin-top: 12rpx;
&::after{
border: 0;
}
}
.giveup{
background-color: transparent;
color: color(tb);
border: 1px solid #e0e0e0;
margin-right: 16px;
}
}
}
</style>
组件还是得慢慢改,还是没有封装的特别完美,有需要的大家就copy走,自己再改改~
具体样式如下: