You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
449 lines
9.5 KiB
449 lines
9.5 KiB
<template> |
|
<view class="uni-stat__select"> |
|
<span v-if="label" class="uni-label-text hide-on-phone">{{label + ':'}}</span> |
|
<view class="uni-stat-box" :class="{'uni-stat__actived': current}"> |
|
<view class="uni-select" :class="{'uni-select--disabled':disabled}"> |
|
<view class="uni-select__input-box" @click="toggleSelector"> |
|
<view v-if="current" class="uni-select__input-text">{{current}}</view> |
|
<view v-else class="uni-select__input-text uni-select__input-placeholder">{{typePlaceholder}}</view> |
|
<uni-icons v-if="current && clear" type="clear" color="#c0c4cc" size="24" @click="clearVal" /> |
|
<uni-icons v-else :type="showSelector? 'top' : 'bottom'" size="14" color="#999" /> |
|
</view> |
|
<view class="uni-select--mask" v-if="showSelector" @click="toggleSelector" /> |
|
<view class="uni-select__selector" v-if="showSelector"> |
|
<view class="uni-popper__arrow"></view> |
|
<scroll-view scroll-y="true" class="uni-select__selector-scroll"> |
|
<view class="uni-select__selector-empty" v-if="mixinDatacomResData.length === 0"> |
|
<text>{{emptyTips}}</text> |
|
</view> |
|
<view v-else class="uni-select__selector-item" v-for="(item,index) in mixinDatacomResData" :key="index" |
|
@click="change(item)"> |
|
<text :class="{'uni-select__selector__disabled': item.disable}">{{formatItemName(item)}}</text> |
|
</view> |
|
</scroll-view> |
|
</view> |
|
</view> |
|
</view> |
|
</view> |
|
</template> |
|
|
|
<script> |
|
/** |
|
* DataChecklist 数据选择器 |
|
* @description 通过数据渲染的下拉框组件 |
|
* @tutorial https://uniapp.dcloud.io/component/uniui/uni-data-select |
|
* @property {String} value 默认值 |
|
* @property {Array} localdata 本地数据 ,格式 [{text:'',value:''}] |
|
* @property {Boolean} clear 是否可以清空已选项 |
|
* @property {Boolean} emptyText 没有数据时显示的文字 ,本地数据无效 |
|
* @property {String} label 左侧标题 |
|
* @property {String} placeholder 输入框的提示文字 |
|
* @property {Boolean} disabled 是否禁用 |
|
* @event {Function} change 选中发生变化触发 |
|
*/ |
|
|
|
export default { |
|
name: "uni-stat-select", |
|
mixins: [uniCloud.mixinDatacom || {}], |
|
data() { |
|
return { |
|
showSelector: false, |
|
current: '', |
|
mixinDatacomResData: [], |
|
apps: [], |
|
channels: [] |
|
}; |
|
}, |
|
props: { |
|
localdata: { |
|
type: Array, |
|
default () { |
|
return [] |
|
} |
|
}, |
|
value: { |
|
type: [String, Number], |
|
default: '' |
|
}, |
|
modelValue: { |
|
type: [String, Number], |
|
default: '' |
|
}, |
|
label: { |
|
type: String, |
|
default: '' |
|
}, |
|
placeholder: { |
|
type: String, |
|
default: '请选择' |
|
}, |
|
emptyTips: { |
|
type: String, |
|
default: '无选项' |
|
}, |
|
clear: { |
|
type: Boolean, |
|
default: true |
|
}, |
|
defItem: { |
|
type: Number, |
|
default: 0 |
|
}, |
|
disabled: { |
|
type: Boolean, |
|
default: false |
|
} |
|
}, |
|
created() { |
|
this.last = `${this.collection}_last_selected_option_value` |
|
if (this.collection && !this.localdata.length) { |
|
this.query(); |
|
} |
|
}, |
|
computed: { |
|
typePlaceholder() { |
|
const text = { |
|
'opendb-stat-app-versions': '版本', |
|
'opendb-app-channels': '渠道', |
|
'opendb-app-list': '应用' |
|
} |
|
const common = this.placeholder |
|
const placeholder = text[this.collection] |
|
return placeholder ? |
|
common + placeholder : |
|
common |
|
} |
|
}, |
|
watch: { |
|
localdata: { |
|
immediate: true, |
|
handler(val, old) { |
|
if (Array.isArray(val) && old !== val) { |
|
this.mixinDatacomResData = val |
|
} |
|
} |
|
}, |
|
// #ifndef VUE3 |
|
value() { |
|
this.initDefVal() |
|
}, |
|
// #endif |
|
// #ifdef VUE3 |
|
modelValue() { |
|
this.initDefVal() |
|
}, |
|
// #endif |
|
mixinDatacomResData: { |
|
immediate: true, |
|
handler(val) { |
|
if (val.length) { |
|
this.initDefVal() |
|
} |
|
} |
|
} |
|
}, |
|
methods: { |
|
// 执行数据库查询 |
|
query(){ |
|
this.mixinDatacomEasyGet(); |
|
}, |
|
// 监听查询条件变更事件 |
|
onMixinDatacomPropsChange(){ |
|
this.query(); |
|
}, |
|
initDefVal() { |
|
let defValue = '' |
|
if ((this.value || this.value === 0) && !this.isDisabled(this.value)) { |
|
defValue = this.value |
|
} else if ((this.modelValue || this.modelValue === 0) && !this.isDisabled(this.modelValue)) { |
|
defValue = this.modelValue |
|
} else { |
|
let strogeValue |
|
if (this.collection) { |
|
strogeValue = uni.getStorageSync(this.last) |
|
} |
|
if (strogeValue || strogeValue === 0) { |
|
defValue = strogeValue |
|
} else { |
|
let defItem = '' |
|
if (this.defItem > 0 && this.defItem <= this.mixinDatacomResData.length) { |
|
defItem = this.mixinDatacomResData[this.defItem - 1].value |
|
} |
|
defValue = defItem |
|
} |
|
if (defValue || defValue === 0) { |
|
this.emit(defValue) |
|
} |
|
} |
|
const def = this.mixinDatacomResData.find(item => item.value === defValue) |
|
this.current = def ? this.formatItemName(def) : '' |
|
}, |
|
|
|
/** |
|
* @param {[String, Number]} value |
|
* 判断用户给的 value 是否同时为禁用状态 |
|
*/ |
|
isDisabled(value) { |
|
let isDisabled = false; |
|
|
|
this.mixinDatacomResData.forEach(item => { |
|
if (item.value === value) { |
|
isDisabled = item.disable |
|
} |
|
}) |
|
|
|
return isDisabled; |
|
}, |
|
|
|
clearVal() { |
|
this.emit('') |
|
if (this.collection) { |
|
uni.removeStorageSync(this.last) |
|
} |
|
}, |
|
change(item) { |
|
if (!item.disable) { |
|
this.showSelector = false |
|
this.current = this.formatItemName(item) |
|
this.emit(item.value) |
|
} |
|
}, |
|
emit(val) { |
|
this.$emit('change', val) |
|
this.$emit('input', val) |
|
this.$emit('update:modelValue', val) |
|
if (this.collection) { |
|
uni.setStorageSync(this.last, val) |
|
} |
|
}, |
|
|
|
toggleSelector() { |
|
if (this.disabled) { |
|
return |
|
} |
|
|
|
this.showSelector = !this.showSelector |
|
}, |
|
formatItemName(item) { |
|
let { |
|
text, |
|
value, |
|
channel_code |
|
} = item |
|
channel_code = channel_code ? `(${channel_code})` : '' |
|
return this.collection.indexOf('app-list') > 0 ? |
|
`${text}(${value})` : |
|
( |
|
text ? |
|
text : |
|
`未命名${channel_code}` |
|
) |
|
} |
|
} |
|
} |
|
</script> |
|
|
|
<style lang="scss"> |
|
$uni-base-color: #6a6a6a !default; |
|
$uni-main-color: #333 !default; |
|
$uni-secondary-color: #909399 !default; |
|
$uni-border-3: #e5e5e5; |
|
|
|
|
|
/* #ifndef APP-NVUE */ |
|
@media screen and (max-width: 500px) { |
|
.hide-on-phone { |
|
display: none; |
|
} |
|
} |
|
|
|
/* #endif */ |
|
.uni-stat__select { |
|
display: flex; |
|
align-items: center; |
|
// padding: 15px; |
|
// cursor: pointer; |
|
width: 100%; |
|
flex: 1; |
|
box-sizing: border-box; |
|
} |
|
|
|
.uni-stat-box { |
|
width: 100%; |
|
flex: 1; |
|
} |
|
|
|
.uni-stat__actived { |
|
width: 100%; |
|
flex: 1; |
|
// outline: 1px solid #2979ff; |
|
} |
|
|
|
.uni-label-text { |
|
font-size: 14px; |
|
font-weight: bold; |
|
color: $uni-base-color; |
|
margin: auto 0; |
|
margin-right: 5px; |
|
} |
|
|
|
.uni-select { |
|
font-size: 14px; |
|
border: 1px solid $uni-border-3; |
|
box-sizing: border-box; |
|
border-radius: 4px; |
|
padding: 0 5px; |
|
padding-left: 10px; |
|
position: relative; |
|
/* #ifndef APP-NVUE */ |
|
display: flex; |
|
user-select: none; |
|
/* #endif */ |
|
flex-direction: row; |
|
align-items: center; |
|
border-bottom: solid 1px $uni-border-3; |
|
width: 100%; |
|
flex: 1; |
|
height: 35px; |
|
|
|
&--disabled { |
|
background-color: #f5f7fa; |
|
cursor: not-allowed; |
|
} |
|
} |
|
|
|
.uni-select__label { |
|
font-size: 16px; |
|
// line-height: 22px; |
|
height: 35px; |
|
padding-right: 10px; |
|
color: $uni-secondary-color; |
|
} |
|
|
|
.uni-select__input-box { |
|
height: 35px; |
|
position: relative; |
|
/* #ifndef APP-NVUE */ |
|
display: flex; |
|
/* #endif */ |
|
flex: 1; |
|
flex-direction: row; |
|
align-items: center; |
|
} |
|
|
|
.uni-select__input { |
|
flex: 1; |
|
font-size: 14px; |
|
height: 22px; |
|
line-height: 22px; |
|
} |
|
|
|
.uni-select__input-plac { |
|
font-size: 14px; |
|
color: $uni-secondary-color; |
|
} |
|
|
|
.uni-select__selector { |
|
/* #ifndef APP-NVUE */ |
|
box-sizing: border-box; |
|
/* #endif */ |
|
position: absolute; |
|
top: calc(100% + 12px); |
|
left: 0; |
|
width: 100%; |
|
background-color: #FFFFFF; |
|
border: 1px solid #EBEEF5; |
|
border-radius: 6px; |
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); |
|
z-index: 3; |
|
padding: 4px 0; |
|
} |
|
|
|
.uni-select__selector-scroll { |
|
/* #ifndef APP-NVUE */ |
|
max-height: 200px; |
|
box-sizing: border-box; |
|
/* #endif */ |
|
} |
|
|
|
.uni-select__selector-empty, |
|
.uni-select__selector-item { |
|
/* #ifndef APP-NVUE */ |
|
display: flex; |
|
// cursor: pointer; |
|
/* #endif */ |
|
line-height: 35px; |
|
font-size: 14px; |
|
text-align: center; |
|
/* border-bottom: solid 1px $uni-border-3; */ |
|
padding: 0px 10px; |
|
} |
|
|
|
.uni-select__selector-item:hover { |
|
background-color: #f9f9f9; |
|
} |
|
|
|
.uni-select__selector-empty:last-child, |
|
.uni-select__selector-item:last-child { |
|
/* #ifndef APP-NVUE */ |
|
border-bottom: none; |
|
/* #endif */ |
|
} |
|
|
|
.uni-select__selector__disabled { |
|
opacity: 0.4; |
|
cursor: default; |
|
} |
|
|
|
/* picker 弹出层通用的指示小三角 */ |
|
.uni-popper__arrow, |
|
.uni-popper__arrow::after { |
|
position: absolute; |
|
display: block; |
|
width: 0; |
|
height: 0; |
|
border-color: transparent; |
|
border-style: solid; |
|
border-width: 6px; |
|
} |
|
|
|
.uni-popper__arrow { |
|
filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03)); |
|
top: -6px; |
|
left: 10%; |
|
margin-right: 3px; |
|
border-top-width: 0; |
|
border-bottom-color: #EBEEF5; |
|
} |
|
|
|
.uni-popper__arrow::after { |
|
content: " "; |
|
top: 1px; |
|
margin-left: -6px; |
|
border-top-width: 0; |
|
border-bottom-color: #fff; |
|
} |
|
|
|
.uni-select__input-text { |
|
// width: 280px; |
|
width: 100%; |
|
color: $uni-main-color; |
|
white-space: nowrap; |
|
text-overflow: ellipsis; |
|
-o-text-overflow: ellipsis; |
|
overflow: hidden; |
|
} |
|
|
|
.uni-select__input-placeholder { |
|
color: $uni-base-color; |
|
font-size: 12px; |
|
} |
|
|
|
.uni-select--mask { |
|
position: fixed; |
|
top: 0; |
|
bottom: 0; |
|
right: 0; |
|
left: 0; |
|
} |
|
</style>
|
|
|