| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465 |
- <template>
- <view class="m-mul-picker" v-if="showMulPicker">
- <uni-transition
- :mode-class="['fade']"
- :styles="maskClass"
- :duration="duration"
- :show="showTrans"
- @click="maskTap"
- />
- <uni-transition :mode-class="['slide-bottom']" :styles="transClass" :duration="duration" :show="showTrans">
- <view class="m-mul-body">
- <view class="m-body-top">
- <view class="m-body-top-btn" @click="mulCancel">
- <text
- class="m--cancel-text"
- :style="{ color: cancelBtn.color, 'font-size': cancelBtn.fontSize }"
- >
- {{ cancelBtn.text }}
- </text>
- </view>
- <view class="m-body-title">
- <text
- class="m--title-text"
- :style="{ color: pickerTitle.color, 'font-size': pickerTitle.fontSize }"
- >
- {{ pickerTitle.text }}
- </text>
- </view>
- <view class="m-body-top-btn" @click="mulConfirm">
- <text
- class="m--confirm-text"
- :style="{ color: confirmBtn.color, 'font-size': confirmBtn.fontSize }"
- >
- {{ confirmBtn.text }}
- </text>
- </view>
- </view>
- <view class="m-body-content">
- <view class="m-search-content" v-if="openSearch">
- <view class="m-search-input">
- <uni-icons type="search" :size="searchIconSize" :color="searchIconColor"></uni-icons>
- <input
- class="m-uni-input"
- :style="'font-size:' + searchFontsize + ';color:' + searchColor"
- :placeholder="searchPlaceholder"
- confirm-type="search"
- v-model="searchVal"
- adjust-position
- @confirm="searchConfirm"
- />
- <uni-icons
- v-if="searchVal != ''"
- type="clear"
- :size="searchIconSize"
- :color="searchIconColor"
- @click="clearSearchVal"
- ></uni-icons>
- </view>
- </view>
- <scroll-view class="m-body-scroll" scroll-y="true">
- <template v-if="dataList.length">
- <template v-for="(item, index) in dataList">
- <view
- class="m--scroll-item"
- :key="index"
- :class="{ 'item-active': selectedVals.includes(item[mapKeys.value]) }"
- @click="selectedItem(item)"
- v-if="filterSearch(item)"
- >
- <text class="m-s-item-text" :style="{ 'text-align': textAlign }">
- {{ item[mapKeys.label] }}
- </text>
- <view class="m--selected-icon" v-if="selectedVals.includes(item[mapKeys.value])">
- <uni-icons type="checkmarkempty" color="#2F77F1" size="18"></uni-icons>
- </view>
- </view>
- </template>
- </template>
- <template v-else>
- <view class="mul-picker-empty">
- <text class="empty-text">{{ emptyText }}</text>
- </view>
- </template>
- </scroll-view>
- </view>
- </view>
- </uni-transition>
- </view>
- </template>
- <script>
- export default {
- name: 'm-multiple-picker',
- props: {
- // 取消按钮自定义
- cancelBtn: {
- type: Object,
- default: () => ({
- text: '取消',
- color: '#666666',
- fontSize: '32rpx'
- })
- },
- // 确定按钮自定义
- confirmBtn: {
- type: Object,
- default: () => ({
- text: '确定',
- color: '#2f77f1',
- fontSize: '32rpx'
- })
- },
- // picker标题
- pickerTitle: {
- type: Object,
- default: () => ({
- text: '请选择',
- color: '#101010',
- fontSize: '32rpx'
- })
- },
- // key和value字段映射
- mapKeys: {
- type: [Object],
- default: () => ({
- label: 'label',
- value: 'value'
- })
- },
- // 是否允许点击mask关闭
- maskClick: {
- type: Boolean,
- default: true
- },
- // 数据
- dataList: {
- type: Array,
- default: () => []
- },
- // 默认选中
- checkedVals: {
- type: Array,
- default: () => []
- },
- // 无数据显示文案
- emptyText: {
- type: String,
- default: '暂无数据'
- },
- // 设置选项的对齐方式 left center right
- textAlign: {
- type: String,
- default: 'center'
- },
- // 设置picker 单选single 多选multiple,默认多选
- selectType: {
- type: String,
- default: 'multiple'
- },
- //S 搜索框设置
- // 是否开启搜索框 默认关闭
- openSearch: {
- type: Boolean,
- default: false
- },
- // 图标大小
- searchIconSize: {
- type: String,
- default: '16'
- },
- // 图标颜色
- searchIconColor: {
- type: String,
- default: '#666666'
- },
- // input输入字体大小
- searchFontsize: {
- type: String,
- default: '24rpx'
- },
- // input输入字体颜色
- searchColor: {
- type: String,
- default: '#333333'
- },
- // 占位符
- searchPlaceholder: {
- type: String,
- default: '请输入'
- }
- //E 搜索框设置
- },
- data() {
- return {
- duration: 300,
- maskClass: {
- position: 'fixed',
- bottom: 0,
- top: 0,
- left: 0,
- right: 0,
- backgroundColor: 'rgba(0, 0, 0, 0.3)'
- },
- transClass: {
- position: 'fixed',
- left: 0,
- right: 0,
- bottom: 0
- },
- showMulPicker: false,
- showTrans: false,
- selectedVals: [],
- searchVal: ''
- };
- },
- methods: {
- selectedItem(item) {
- if (this.selectType == 'multiple') {
- this.selectedVals.indexOf(item[this.mapKeys.value]) > -1
- ? this.selectedVals.splice(this.selectedVals.indexOf(item[this.mapKeys.value]), 1)
- : this.selectedVals.push(item[this.mapKeys.value]);
- } else {
- // 单选,可以取消选中
- if (this.selectedVals.length > 0) {
- if (this.selectedVals.indexOf(item[this.mapKeys.value]) > -1) {
- this.selectedVals.splice(this.selectedVals.indexOf(item[this.mapKeys.value]), 1);
- } else {
- this.selectedVals = [];
- this.selectedVals.push(item[this.mapKeys.value]);
- }
- } else {
- this.selectedVals.push(item[this.mapKeys.value]);
- }
- }
- },
- // 打开picker
- openMulpicker() {
- this.selectedVals = JSON.parse(JSON.stringify(this.checkedVals));
- this.showMulPicker = true;
- this.$nextTick(() => {
- clearTimeout(this.timer);
- this.timer = setTimeout(() => {
- this.showTrans = true;
- }, 50);
- });
- this.$emit('change', {
- show: true,
- selectedVals: this.selectedVals
- });
- },
- // 关闭picker
- closeMulpicker(type) {
- this.showTrans = false;
- this.$nextTick(() => {
- clearTimeout(this.timer);
- this.timer = setTimeout(() => {
- this.$emit('change', {
- show: false,
- selectedVals: this.selectedVals
- });
- this.showMulPicker = false;
- }, 300);
- });
- },
- mulCancel() {
- this.closeMulpicker();
- },
- mulConfirm() {
- let selectedObj = this.dataList.filter((item) => {
- return this.selectedVals.includes(item[this.mapKeys.value]);
- });
- this.$nextTick(() => {
- this.$emit('mulConfirm', {
- value: this.selectedVals,
- objValue: selectedObj
- });
- });
- this.closeMulpicker();
- },
- maskTap() {
- if (!this.maskClick) return;
- this.closeMulpicker();
- },
- // 搜索筛选关键字
- searchConfirm(e) {
- let { value } = e.detail;
- this.searchVal = value;
- },
- clearSearchVal() {
- this.searchVal = '';
- },
- // 筛选 显示
- filterSearch(item) {
- if (this.searchVal) {
- return item[this.mapKeys.label].includes(this.searchVal);
- } else {
- return true;
- }
- }
- }
- };
- </script>
- <style scoped>
- .m-mul-picker {
- position: absolute;
- bottom: 0;
- width: 750rpx;
- /* height: 620rpx; */
- }
- .m-mul-body {
- width: 750rpx;
- height: 620rpx;
- background-color: #fff;
- /* #ifndef APP-NVUE */
- display: flex;
- /* #endif */
- flex-direction: column;
- }
- .m-body-top {
- /* #ifndef APP-NVUE */
- display: flex;
- box-sizing: border-box;
- /* #endif */
- flex-direction: row;
- justify-content: space-between;
- align-items: center;
- height: 88rpx;
- }
- .m-body-top-btn {
- height: 88rpx;
- padding: 0 30rpx;
- /* #ifndef APP-NVUE */
- display: flex;
- box-sizing: border-box;
- /* #endif */
- flex-direction: row;
- justify-content: space-between;
- align-items: center;
- }
- .m--cancel-text {
- color: #666666;
- font-size: 32rpx;
- }
- .m--confirm-text {
- color: #2f77f1;
- font-size: 32rpx;
- }
- .m-body-title {
- flex: 1;
- height: 88rpx;
- flex-direction: row;
- justify-content: center;
- align-items: center;
- /* #ifndef APP-NVUE */
- display: flex;
- box-sizing: border-box;
- /* #endif */
- }
- .m--title-text {
- color: #101010;
- font-size: 32rpx;
- lines: 1;
- text-overflow: ellipsis;
- }
- .m-body-content {
- flex: 1;
- }
- /* new 筛选 */
- .m-search-content {
- width: 750rpx;
- height: 80rpx;
- padding: 6rpx 30rpx;
- /* #ifndef APP-NVUE */
- box-sizing: border-box;
- /* #endif */
- }
- .m-search-input {
- flex: 1;
- border: 2rpx solid #d8e3ff;
- /* #ifndef APP-NVUE */
- display: flex;
- box-sizing: border-box;
- /* #endif */
- flex-direction: row;
- align-items: center;
- border-radius: 8rpx;
- padding: 0 20rpx;
- }
- .m-uni-input {
- flex: 1;
- font-size: 12px;
- padding: 0 8px;
- }
- .m-body-scroll {
- flex: 1;
- /* #ifndef APP-NVUE */
- display: flex;
- /* #endif */
- }
- /* #ifndef APP-NVUE */
- /deep/ .uni-scroll-view {
- flex: 1;
- /* #ifndef APP-NVUE */
- display: flex;
- /* #endif */
- }
- /deep/ .uni-scroll-view-content {
- flex: 1;
- /* #ifndef APP-NVUE */
- display: flex;
- /* #endif */
- flex-direction: column;
- }
- /* #endif */
- .m--scroll-item {
- width: 750rpx;
- padding: 0 30rpx;
- /* #ifndef APP-NVUE */
- display: flex;
- box-sizing: border-box;
- flex-shrink: 0;
- /* #endif */
- flex-direction: row;
- align-items: center;
- justify-content: flex-start;
- position: relative;
- height: 80rpx;
- }
- .m-s-item-text {
- width: 640rpx;
- lines: 1;
- text-overflow: ellipsis;
- color: #101010;
- font-size: 28rpx;
- }
- .m--selected-icon {
- position: absolute;
- right: 30rpx;
- }
- .item-active .m-s-item-text {
- color: #2f77f1;
- }
- .mul-picker-empty {
- flex: 1;
- /* #ifndef APP-NVUE */
- display: flex;
- /* #endif */
- flex-direction: row;
- justify-content: center;
- align-items: center;
- }
- .empty-text {
- font-size: 28rpx;
- color: #666666;
- }
- </style>
|