forked from ccsens_fe/tall-mui-3
6 changed files with 103 additions and 362 deletions
@ -0,0 +1,84 @@ |
|||||
|
<template> |
||||
|
<view class="my-3" v-if="allMembers && allMembers.length"> |
||||
|
<view class="flex justify-between"> |
||||
|
<view class="flex flex-wrap text-center items-center"> |
||||
|
<u-tag |
||||
|
:type="member.checked ? 'primary' : 'info'" |
||||
|
v-for="(member, index) in topMembers" |
||||
|
:key="member.memberId" |
||||
|
class="mb-2 mr-3" |
||||
|
style="width: 60px" |
||||
|
:text="member.name" |
||||
|
:closeable="false" |
||||
|
@click="tagClick(index, member, 'topMembers')" |
||||
|
/> |
||||
|
<span class="ml-2" @click="show = !show">...</span> |
||||
|
</view> |
||||
|
</view> |
||||
|
<!-- 折叠起来的 --> |
||||
|
<view class="flex flex-wrap text-center items-center" v-if="show"> |
||||
|
<u-tag |
||||
|
:type="member.checked ? 'primary' : 'info'" |
||||
|
v-for="(member, index) in bottomMembers" |
||||
|
:key="member.memberId" |
||||
|
class="mb-2 mr-3" |
||||
|
style="width: 60px" |
||||
|
:text="member.name" |
||||
|
:closeable="false" |
||||
|
@click="tagClick(index, member, 'bottomMembers')" |
||||
|
/> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { mapState } from 'vuex'; |
||||
|
|
||||
|
export default { |
||||
|
props: { |
||||
|
checkerList: { |
||||
|
default: () => [], |
||||
|
type: Array, |
||||
|
}, |
||||
|
}, |
||||
|
|
||||
|
data() { |
||||
|
return { allMembers: [], show: false, topMembers: [], bottomMembers: [] }; |
||||
|
}, |
||||
|
|
||||
|
computed: mapState('role', ['members']), |
||||
|
|
||||
|
mounted() { |
||||
|
if (this.members && this.members.length) { |
||||
|
this.allMembers = this.members; |
||||
|
// TODO: 等后台返回默认检查人后修改 |
||||
|
this.allMembers.forEach(item => { |
||||
|
item.checked = false; |
||||
|
}); |
||||
|
this.topMembers = this.members.slice(0, 3); |
||||
|
this.bottomMembers = this.members.slice(3); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
methods: { |
||||
|
tagClick(index, item, membersType) { |
||||
|
// 点击选择或取消选择 |
||||
|
const arr = this.$u.deepClone(this[membersType]); |
||||
|
arr[index].checked = !arr[index].checked; |
||||
|
this[membersType] = [...arr]; |
||||
|
// 将选中的id传给checkerList |
||||
|
this.$emit('setCheckerList', arr[index].checked, item); |
||||
|
}, |
||||
|
|
||||
|
// 清空所有选中的检查人 |
||||
|
clearChecked() { |
||||
|
for (let i = 0; i < this.topMembers.length; i++) { |
||||
|
this.topMembers[i].checked = false; |
||||
|
} |
||||
|
for (let i = 0; i < this.bottomMembers.length; i++) { |
||||
|
this.bottomMembers[i].checked = false; |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
@ -1,342 +0,0 @@ |
|||||
<template> |
|
||||
<view class="main"> |
|
||||
<view :style="disabled ? 'background-color:#f5f7fa' : ''" class="input"> |
|
||||
<input |
|
||||
:placeholder="placeholder" |
|
||||
:style="disabled ? 'color:#c0c4cc' : ''" |
|
||||
@click="showModal" |
|
||||
class="text-sm" |
|
||||
disabled |
|
||||
v-model="_value" |
|
||||
/> |
|
||||
<u-icon @click="empty" color="#C0C4CC" name="close-circle-fill" size="32" v-if="clearable && !disabled && showClearable"></u-icon> |
|
||||
</view> |
|
||||
<view :class="isShowModal ? 'show' : ''" @tap="hideModal" class="select-modal"> |
|
||||
<view :style="{ backgroundColor: bgColor }" @tap.stop class="select-dialog"> |
|
||||
<view class="select-bar bg-white"> |
|
||||
<view @tap="cancelClick" class="action text-gray">{{ cancelText }}</view> |
|
||||
<view @tap="confirmClick" class="action text-blue">{{ confirmText }}</view> |
|
||||
</view> |
|
||||
<view class="select-content"> |
|
||||
<view |
|
||||
:key="index" |
|
||||
:style="valueIndexOf(item) ? 'color:' + selectColor + ';background-color:' + selectBgColor + ';' : 'color:' + color + ';'" |
|
||||
@click="select(item)" |
|
||||
class="select-item" |
|
||||
v-for="(item, index) in list" |
|
||||
> |
|
||||
<view class="title">{{ getLabelKeyValue(item) }}</view> |
|
||||
<u-icon name="checkbox-mark" v-if="valueIndexOf(item)"></u-icon> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
export default { |
|
||||
data() { |
|
||||
return { isShowModal: false, showClearable: false }; |
|
||||
}, |
|
||||
props: { |
|
||||
value: { |
|
||||
type: [Number, String, Array, Object], |
|
||||
default: null, |
|
||||
}, |
|
||||
placeholder: { |
|
||||
// 占位符 |
|
||||
default: '', |
|
||||
type: String, |
|
||||
}, |
|
||||
multiple: { |
|
||||
// 是否多选 |
|
||||
default: false, |
|
||||
type: Boolean, |
|
||||
}, |
|
||||
list: { |
|
||||
default: () => [], |
|
||||
type: Array, |
|
||||
}, |
|
||||
valueKey: { |
|
||||
// 指定list中valueKey的值作为下拉框绑定内容 |
|
||||
default: 'value', |
|
||||
type: String, |
|
||||
}, |
|
||||
labelKey: { |
|
||||
// 指定list中labelKey的值作为下拉框显示内容 |
|
||||
default: 'label', |
|
||||
type: String, |
|
||||
}, |
|
||||
disabled: { |
|
||||
default: false, |
|
||||
type: Boolean, |
|
||||
}, |
|
||||
clearable: { |
|
||||
default: false, |
|
||||
type: Boolean, |
|
||||
}, |
|
||||
cancelText: { |
|
||||
default: '取消', |
|
||||
type: String, |
|
||||
}, |
|
||||
confirmText: { |
|
||||
default: '确定', |
|
||||
type: String, |
|
||||
}, |
|
||||
color: { |
|
||||
default: '#000000', |
|
||||
type: String, |
|
||||
}, |
|
||||
selectColor: { |
|
||||
default: '#0081ff', |
|
||||
type: String, |
|
||||
}, |
|
||||
bgColor: { |
|
||||
default: '#F1F1F1', |
|
||||
type: String, |
|
||||
}, |
|
||||
selectBgColor: { |
|
||||
default: '#FFFFFF', |
|
||||
type: String, |
|
||||
}, |
|
||||
}, |
|
||||
computed: { |
|
||||
_value: { |
|
||||
get() { |
|
||||
return this.get_value(this.value); |
|
||||
}, |
|
||||
set(val) { |
|
||||
this.$emit('change', val); |
|
||||
}, |
|
||||
}, |
|
||||
}, |
|
||||
created() {}, |
|
||||
methods: { |
|
||||
get_value(val) { |
|
||||
// 将数组值转换为以,隔开的字符串 |
|
||||
if (val || val === 0) { |
|
||||
if (Array.isArray(val)) { |
|
||||
if (val.length > 0) { |
|
||||
this.showClearable = true; |
|
||||
} else { |
|
||||
this.showClearable = false; |
|
||||
} |
|
||||
let chooseAttr = []; |
|
||||
val.forEach(item => { |
|
||||
let choose = this.list.find(temp => { |
|
||||
let val_val = this.getValueKeyValue(temp); |
|
||||
return item === val_val; |
|
||||
}); |
|
||||
chooseAttr.push(choose); |
|
||||
}); |
|
||||
let values = chooseAttr.map(temp => this.getLabelKeyValue(temp)).join(','); |
|
||||
return values; |
|
||||
} else { |
|
||||
let choose = this.list.find(temp => { |
|
||||
let val_val = this.getValueKeyValue(temp); |
|
||||
return val === val_val; |
|
||||
}); |
|
||||
return this.getLabelKeyValue(choose); |
|
||||
} |
|
||||
} else { |
|
||||
console.log('val2', val); |
|
||||
return ''; |
|
||||
} |
|
||||
}, |
|
||||
select(item) { |
|
||||
// 点击选项 |
|
||||
let val = this.getValueKeyValue(item); |
|
||||
if (this.multiple) { |
|
||||
let _value = this.value; |
|
||||
let index = _value.indexOf(val); |
|
||||
if (index != -1) { |
|
||||
_value.splice(index, 1); |
|
||||
this.$emit('change', _value); |
|
||||
} else { |
|
||||
_value.push(val); |
|
||||
this.$emit('change', _value); |
|
||||
} |
|
||||
} else { |
|
||||
this.$emit('change', val); |
|
||||
this.hideModal(); |
|
||||
} |
|
||||
}, |
|
||||
valueIndexOf(item) { |
|
||||
let val = this.getValueKeyValue(item); |
|
||||
if (Array.isArray(this.value)) { |
|
||||
return this.value.indexOf(val) != -1; |
|
||||
} else { |
|
||||
return this.value === val; |
|
||||
} |
|
||||
}, |
|
||||
getLabelKeyValue(item) { |
|
||||
// 获取label |
|
||||
return item[this.labelKey]; |
|
||||
}, |
|
||||
getValueKeyValue(item) { |
|
||||
// 获取value |
|
||||
return item[this.valueKey]; |
|
||||
}, |
|
||||
empty() { |
|
||||
// 清空 |
|
||||
if (this.multiple) { |
|
||||
this.$emit('change', []); |
|
||||
} else { |
|
||||
this.$emit('change', ''); |
|
||||
} |
|
||||
}, |
|
||||
cancelClick() { |
|
||||
// 点击取消 |
|
||||
this.$emit('cancel', this._value); |
|
||||
this.hideModal(); |
|
||||
}, |
|
||||
confirmClick() { |
|
||||
// 点击确定 |
|
||||
this.$emit('confirm', this._value); |
|
||||
this.hideModal(); |
|
||||
}, |
|
||||
showModal() { |
|
||||
// 显示model |
|
||||
if (!this.disabled) { |
|
||||
this.isShowModal = true; |
|
||||
} |
|
||||
}, |
|
||||
hideModal() { |
|
||||
// 隐藏model |
|
||||
this.isShowModal = false; |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
||||
<style> |
|
||||
@font-face { |
|
||||
font-family: 'selectIcon'; |
|
||||
src: url('//at.alicdn.com/t/font_1833441_ycfzdhg2u3.eot?t=1590375117208'); /* IE9 */ |
|
||||
src: url('//at.alicdn.com/t/font_1833441_ycfzdhg2u3.eot?t=1590375117208#iefix') format('embedded-opentype'), |
|
||||
/* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ url('//at.alicdn.com/t/font_1833441_ycfzdhg2u3.svg?t=1590375117208#selectIcon') |
|
||||
format('svg'); /* iOS 4.1- */ |
|
||||
} |
|
||||
|
|
||||
.selectIcon { |
|
||||
font-family: 'selectIcon' !important; |
|
||||
font-size: 16px; |
|
||||
font-style: normal; |
|
||||
-webkit-font-smoothing: antialiased; |
|
||||
-moz-osx-font-smoothing: grayscale; |
|
||||
} |
|
||||
|
|
||||
.icongou:before { |
|
||||
content: '\e61c'; |
|
||||
} |
|
||||
|
|
||||
.iconcross:before { |
|
||||
content: '\e61a'; |
|
||||
} |
|
||||
</style> |
|
||||
<style lang="scss" scoped> |
|
||||
.main { |
|
||||
font-size: 30rpx; |
|
||||
} |
|
||||
.bg-white { |
|
||||
background-color: #ffffff; |
|
||||
} |
|
||||
.text-blue { |
|
||||
color: #0081ff; |
|
||||
} |
|
||||
.text-green { |
|
||||
color: #39b54a; |
|
||||
} |
|
||||
.input { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
font-size: 28rpx; |
|
||||
height: 60rpx; |
|
||||
padding: 10rpx 20rpx; |
|
||||
border-radius: 8rpx; |
|
||||
border-style: solid; |
|
||||
border-width: 1rpx; |
|
||||
border-color: rgb(220, 223, 230); |
|
||||
input { |
|
||||
flex: 1; |
|
||||
} |
|
||||
} |
|
||||
.select-modal { |
|
||||
position: fixed; |
|
||||
top: 0; |
|
||||
right: 0; |
|
||||
bottom: 0; |
|
||||
left: 0; |
|
||||
z-index: 9999; |
|
||||
opacity: 0; |
|
||||
outline: 0; |
|
||||
text-align: center; |
|
||||
-ms-transform: scale(1.185); |
|
||||
transform: scale(1.185); |
|
||||
backface-visibility: hidden; |
|
||||
perspective: 2000rpx; |
|
||||
background: rgba(0, 0, 0, 0.6); |
|
||||
transition: all 0.3s ease-in-out 0s; |
|
||||
pointer-events: none; |
|
||||
margin-bottom: -1000rpx; |
|
||||
&::before { |
|
||||
content: '\200B'; |
|
||||
display: inline-block; |
|
||||
height: 100%; |
|
||||
vertical-align: bottom; |
|
||||
} |
|
||||
.select-dialog { |
|
||||
position: relative; |
|
||||
display: inline-block; |
|
||||
margin-left: auto; |
|
||||
margin-right: auto; |
|
||||
background-color: #f8f8f8; |
|
||||
overflow: hidden; |
|
||||
width: 100%; |
|
||||
border-radius: 0; |
|
||||
.select-content { |
|
||||
// background-color: #F1F1F1; |
|
||||
max-height: 420rpx; |
|
||||
overflow: auto; |
|
||||
.select-item { |
|
||||
padding: 20rpx; |
|
||||
display: flex; |
|
||||
.title { |
|
||||
flex: 1; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
.select-modal.show { |
|
||||
opacity: 1; |
|
||||
transition-duration: 0.3s; |
|
||||
-ms-transform: scale(1); |
|
||||
transform: scale(1); |
|
||||
overflow-x: hidden; |
|
||||
overflow-y: auto; |
|
||||
pointer-events: auto; |
|
||||
margin-bottom: 0; |
|
||||
} |
|
||||
.select-bar { |
|
||||
padding: 0 20rpx; |
|
||||
display: flex; |
|
||||
position: relative; |
|
||||
align-items: center; |
|
||||
min-height: 80rpx; |
|
||||
justify-content: space-between; |
|
||||
.action { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
height: 100%; |
|
||||
justify-content: center; |
|
||||
max-width: 100%; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.uni-input-input, |
|
||||
.uni-input-placeholder { |
|
||||
color: #c0c4cc; |
|
||||
font-size: 28rpx; |
|
||||
} |
|
||||
</style> |
|
Loading…
Reference in new issue