init
This commit is contained in:
7
components/op-drop-down/changelog.md
Normal file
7
components/op-drop-down/changelog.md
Normal file
@@ -0,0 +1,7 @@
|
||||
## 1.1.1(2025-03-06)
|
||||
1.1.1
|
||||
## 1.1.0(2025-03-06)
|
||||
1.1.0
|
||||
## 1.0.0(2025-03-05)
|
||||
1.0.0
|
||||
1.0.0
|
||||
244
components/op-drop-down/components/op-cascader/op-cascader.vue
Normal file
244
components/op-drop-down/components/op-cascader/op-cascader.vue
Normal file
@@ -0,0 +1,244 @@
|
||||
<template>
|
||||
<view class="op-cascader" :style="{maxHeight: maxHeight}">
|
||||
<template v-for="(opt, optInx) in newOption" :key="optInx">
|
||||
<view class="cascader-content">
|
||||
<scroll-view :scroll-y="true" style="height: 100%;">
|
||||
<template v-for="(item, index) in opt" :key="index">
|
||||
<view v-if="item._parentId==0 || (optInx >0 && modelValue[optInx-1] == item._parentId)"
|
||||
class="cascader-item" :class="{active:
|
||||
isActive(item,optInx,valueKey)
|
||||
}" @click="select(item[valueKey], optInx, index, item._level)">
|
||||
<view class="cascader-item-label">{{ item[labelKey] }}</view>
|
||||
<template v-if="iconShow">
|
||||
<image v-if="isActive(item,optInx,valueKey)" class="icon"
|
||||
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAOHSURBVHgB7ZldbtpAEMdnFgeBaCV6gnKDkhMUpCbKW9oTRDlB04cS5SnwUFWiL+EEbW+QxzSJFHqCcIOSGyD1I4Hgne44obWNbXb9BQ/8HhJsL+Y/u7O7szMAa9YkAiEFGm2qliq/6rZdeI1CPAegOiFVkbDKz9XnEZIYEqn/IL8LIftn75/2IQUSGbDz6WeDRUMB9mZidWGj1J9TALt30XoygJjEMsARDtYxEjQgBYigX5Cwf3ZUHoIhRgawqxQr42P1iweQBUgnk9/lTr+NI+2v6Dbc+XhbkwW4Uh9rkC1DYUNTdzSETqOtrpqgFl1D9uIZp6O2upO6TuOFI8DiAcWV6SRNDo4IRPOiVYyc4JEG5Og2IeBI2LQZ5U6hLsQTdrnimQcNrCWsRagBzmqzVPH/qBUrt8dhDwNd6NF1fsAKIXHavAzYvQNHwLbgM6wYKK3AUZgbga0Pkzpu2NewggSNwtwIkHWfzS4bAocRum2R4y4fcwagwF3IC5Kdi8NyEwg6Os1VpLvnX5E8BqjJ28htw1Lizw8rbf54flhuE+qMBFUtFba773gMkEI2IA9c4pnt7lg7svW7kccAEuIlZE2AeNV1bd2vo29v8s4BomzdJ6F4B4EvPJeeh2i285qsIKmId8DwSWw0gU1WkNTEOy8LN0D7Farn3StIpBGpip/HO4n5oK0BIjS2u/8DrFAjMhHvPW76XUj7LKpoRxqRWc/LofvKuw8QmqY3go3I0G3I18mW+wJR3sTItLARcN4qO73vGOEibZ/nxJj72jsHbE40xcIzEjPSFs+oaKHvvvYYMC3dDXQncgAeI7IQzxPYH07Pnwe6f04Q8C3Ep/3QL2mLd8R++dYq77vvWf5G7EZYgIQGSMgCCYWe/97cRnZ5VO7rhbb5wptnUI4ocCemqd4BI084+Rt0P9AAZxSAerAikKReWHIrNBa63xjzpjSEZaM03N959xY3oQb03z0bCQnNBMtqcpR41hCVbo+MRp1hI7kUI5QLjwjtN4vS7AvDaaf8o4zI051YvFo0mzqlJ7MCh1DJXsNTmzGPbpNqgYPhF06Kd5tZrk682kxuS5smtbJ4RT41Gpw/TbPIRxI6vHyDIYnKrFy9UYegA0LcRTAss7KfS/iq4vvTOMJnpFLoZl6prJ4qYDec3NJDeqY2M4rFonMUxAFJecOip+PSwKQauWZNRvwFjird3f4t0GAAAAAASUVORK5CYII="
|
||||
mode="aspectFit"></image>
|
||||
<image v-else class="icon"
|
||||
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAQdSURBVHgB7VlbTiJBFC3QGOOHz1/RxOjPGP8HF+C4AMUFDC5AWYfMAtQFyMwC0AXIAgwmRuMP86uJfBhjVOYcUtW5XV0N3dA0TMJJSFc/qLqn7q2q+1BqjDH6QkYlgPv7+1lcNrPZ7I+vr68VXL/hOpfJZPhctVqtJp418IzXa1xrGxsbNZUA+iIAwfNa6AMjbFSQFC5V/M5Apq56RE8EKDguJQidVwkAZGpvb29HW1tbDRUTsQhoU6HgxUBHmUwD2qh+fHzcol1bWFh4WVpa4iyrp6en2efn5xyay5OTk3lobBdC51SQyBkuJ9BIU0VEZAI3Nze5mZmZ3/bAELYCgSpxbRqTwTVTRH8Fq7/G6+vrflRtRCJQr9c3p6am/kg7R/sagx+vr6/HVrvEw8NDDn0dSyIkgUn5GWVtdCVgC8/FNzExcbK2tnamEsTj42Px8/OzZMbBtQkSe91IdCRgm02cmekFWhtyvCbMaaeTOYUS4IKFjV5J4dHe79dkusFBgpO2E7awsx36KplOaDZpCE9wDGpZnxNKy1AK+95JgKYjt0rafBrCG9BEOaa5pyz67AnASWB6evqX+HMl6QUbBRyTB5x45NRCgAD3Z3nCopOyGhIgx5Fo511acGmgKP5USdN0bHBsymDu6XfZ37gI7JoGjv3UTccGT3lxe6DdGQ8+AlSROEgaq6urA9nv44AuCmVhG+bcdtvlex8BqEjaWFWNDjxZbDPyEYC6tkU7kYAjCUCWW9Feke/sNeDZF/yfv2pEQPfctBntyXc2Ac9Vfn9/H9ruYwO2/yJu5+Q7HwHpLscJKgYNKYteyB6y6j+Hj4BxoAh7vx0mpCx0seU7ext9ER/OqdGBtzaxC/nWpm1C3sEFMt/V6GDZNOQkt++tDz12MKdNNSKwDljf+WQfZJfidleNDjxZ7AM2YEIyEgoLItIE3XsZI9vpGx8B7rdQ14V4VFDDh0yiBfyzwDkgzQiMCwwv1ZCgQ1tvEl3ufYAAVSRDORlepg2MfWzaTKS53Puwk1gG1HmkOg5Vyri7uzuUs88soOs7JwEdRJyae6b+uJhUSqDpYC3K2T8NC21DfSGshbKMhNDheRrrwWQDZWQ4Pz8fmlgIJcAdicksua2y40GSYB7WTmVSBpOmd6GjN6rVtmeRuBrEmqDNM4kss4HM0HXLikRKr+tc/rmsDaBdQVWl3EtVRYIa5U5n5aI4YXuJpNcN7KSrGIxpj9h1Ln3KF+RO0xYoZhI5domJuwMGCJiQXvBVvK+hzMR4umEiKf6P7jn+l9cxrbPExN2GC7aTzfdFwEBrowwhtlUC4CHFXa+X0mu/ZdZ2nYtFu17KrHANLqCty35qxokUugldM6ZdswrJaC5nFboZiNRZ8KbQi4uL9TimMsYYA8I/5WtETy5O2jYAAAAASUVORK5CYII="
|
||||
mode="aspectFit"></image>
|
||||
</template>
|
||||
</view>
|
||||
</template>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
defineModel,
|
||||
defineProps,
|
||||
defineEmits,
|
||||
watch
|
||||
} from 'vue';
|
||||
const modelValue = defineModel({
|
||||
type: Array,
|
||||
default: []
|
||||
});
|
||||
const DefProps = defineProps({
|
||||
option: { // tree数据
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
props: { // 属性值
|
||||
type: Object,
|
||||
default: {
|
||||
label: 'label',
|
||||
value: 'value',
|
||||
children: 'children',
|
||||
disabled: 'disabled',
|
||||
}
|
||||
},
|
||||
maxHeight: { //最大下拉高度
|
||||
type: String,
|
||||
default: "400rpx"
|
||||
},
|
||||
iconShow: { // 是由否显示左侧按钮
|
||||
type: Boolean,
|
||||
default: false,
|
||||
}
|
||||
})
|
||||
const Emits = defineEmits(['change'])
|
||||
const newOption = ref([]); // 选项tree
|
||||
const labelKey = ref('label'); // 默认属性key
|
||||
const valueKey = ref('value');
|
||||
const childrenKey = ref('children');
|
||||
const disabled = ref('disabledKey');
|
||||
|
||||
// 配置属性key
|
||||
watch(() => DefProps.props, (newVal, oldVal) => {
|
||||
labelKey.value = newVal.label ?? 'label'
|
||||
valueKey.value = newVal.value ?? 'value'
|
||||
childrenKey.value = newVal.children ?? 'children'
|
||||
disabled.value = newVal.disabledKey ?? 'disabledKey'
|
||||
}, {
|
||||
deep: true,
|
||||
immediate: true
|
||||
})
|
||||
|
||||
// 整理tree数据根据层级分类数组
|
||||
watch(() => DefProps.option, (newVal, oldVal) => {
|
||||
if (newVal) {
|
||||
let tree = treeConfig(newVal);
|
||||
newOption.value = setData(tree);
|
||||
}
|
||||
}, {
|
||||
deep: true,
|
||||
immediate: true
|
||||
});
|
||||
|
||||
const isActive = (item, optInx, valueKey) => {
|
||||
if (item._level !== newOption.value.length) {
|
||||
return modelValue.value[optInx] == item[valueKey]
|
||||
} else {
|
||||
if (modelValue.value[item._level - 1] === undefined) {
|
||||
return false
|
||||
} else {
|
||||
return modelValue.value[item._level - 1].includes(item[valueKey])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 默认tree列表配置,设置父子级关系和层级
|
||||
function treeConfig(arr, parentId = 0, level = 0) {
|
||||
let list = JSON.parse(JSON.stringify(arr))
|
||||
list.forEach(item => {
|
||||
item._parentId = parentId;
|
||||
item._level = level + 1;
|
||||
if (item[childrenKey.value] && item[childrenKey.value].length > 0) {
|
||||
item[childrenKey.value] = treeConfig(item[childrenKey.value], item[valueKey.value], item._level);
|
||||
}
|
||||
})
|
||||
return list
|
||||
}
|
||||
|
||||
// 将tree数据根据层级分类
|
||||
function setData(tree, list = []) {
|
||||
tree.forEach(item => {
|
||||
let obj = {}
|
||||
for (let k in item) {
|
||||
if (k != childrenKey.value) {
|
||||
obj[k] = item[k];
|
||||
}
|
||||
}
|
||||
if (!list[obj._level - 1]) {
|
||||
list[obj._level - 1] = [];
|
||||
}
|
||||
list[obj._level - 1].push(obj);
|
||||
|
||||
if (item[childrenKey.value] && item[childrenKey.value].length > 0) {
|
||||
list = setData(item[childrenKey.value], list)
|
||||
}
|
||||
})
|
||||
return list
|
||||
}
|
||||
|
||||
// 选择
|
||||
function select(value, parentIndex, index, _level) {
|
||||
let arr = JSON.parse(JSON.stringify(modelValue.value))
|
||||
arr[parentIndex] = value;
|
||||
let list = []
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (i <= parentIndex) {
|
||||
list.push(arr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
let origin_list = modelValue.value
|
||||
let current_list = list
|
||||
|
||||
if (JSON.stringify(origin_list.slice(0, newOption.value.length - 1)) === JSON.stringify(current_list.slice(0,
|
||||
newOption.value.length - 1))) {
|
||||
// 将最后一个层级设置为多选
|
||||
if (_level === newOption.value.length) {
|
||||
if (modelValue.value[_level - 1] === undefined) {
|
||||
modelValue.value[_level - 1] = []
|
||||
}
|
||||
|
||||
|
||||
if (modelValue.value[_level - 1].includes(value)) {
|
||||
modelValue.value[_level - 1] = modelValue.value[_level - 1].filter(e => e != value)
|
||||
} else {
|
||||
modelValue.value[_level - 1].push(value)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
modelValue.value = list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Emits('change', modelValue.value, value)
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
page,
|
||||
view,
|
||||
text,
|
||||
swiper,
|
||||
swiper-item,
|
||||
image,
|
||||
navigator,
|
||||
icon,
|
||||
form,
|
||||
input,
|
||||
button {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.op-cascader {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
|
||||
.cascader-content {
|
||||
flex: 1;
|
||||
// overflow: hidden;
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
|
||||
.cascader-item {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-left: 20rpx;
|
||||
padding-right: 8rpx;
|
||||
|
||||
&.active {
|
||||
.cascader-item-label {
|
||||
color: #468AF7;
|
||||
}
|
||||
}
|
||||
|
||||
.cascader-item-label {
|
||||
flex: 1;
|
||||
text-align: left;
|
||||
color: #364462;
|
||||
font-size: 25rpx;
|
||||
line-height: 92rpx;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
|
||||
&.active {
|
||||
color: #468AF7;
|
||||
}
|
||||
}
|
||||
|
||||
>.icon {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cascader-content:first-of-type {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,300 @@
|
||||
<template>
|
||||
<view class="op-dateTime-picker">
|
||||
<view class="dateTime">
|
||||
<!-- 日期时间 -->
|
||||
<view class="dateTime-input" v-if="type.indexOf('range') == -1">
|
||||
<view class="dateTime-label">{{ label }}:</view>
|
||||
<input v-model="timeVal" type="date" :placeholder="placeholder" disabled @click.stop="openTimeSelect()"></input>
|
||||
</view>
|
||||
<!-- 日期时间范围 -->
|
||||
<template v-if="type.indexOf('range') > -1">
|
||||
<view class="dateTime-input">
|
||||
<view class="dateTime-label">开始{{ label }}:</view>
|
||||
<input v-model="timeVals[0]" type="date" :placeholder="startPlaceholder" disabled @click.stop="openTimeSelect(0)"></input>
|
||||
</view>
|
||||
<view class="dateTime-input">
|
||||
<view class="dateTime-label">结束{{ label }}:</view>
|
||||
<input v-model="timeVals[1]" type="date" :placeholder="endPlaceholder" disabled @click.stop="openTimeSelect(1)"></input>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
|
||||
<!-- 下拉选择 -->
|
||||
<view v-if="dateTimeVisible">
|
||||
<picker-view :value="defaultVal" class="pickerView" indicator-class="pickerViewColumn" @change="pickerChange">
|
||||
<picker-view-column :class="{show: type.indexOf('date') > -1 || type.indexOf('year') > -1}">
|
||||
<view class="item" v-for="(item,index) in years" :key="index">{{item}}</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column :class="{show: type.indexOf('date') > -1 || type.indexOf('month') > -1}">
|
||||
<view class="item" v-for="(item,index) in months" :key="index">{{item}}</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column :class="{show: type.indexOf('date') > -1}">
|
||||
<view class="item" v-for="(item,index) in days" :key="index">{{item}}</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column :class="{show: type.indexOf('time') > -1}">
|
||||
<view class="item" v-for="(item,index) in hours" :key="index">{{item}}</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column :class="{show: type.indexOf('time') > -1}">
|
||||
<view class="item" v-for="(item,index) in minutes" :key="index">{{item}}</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, defineModel, defineProps, defineEmits, watch } from 'vue';
|
||||
const modelVal= defineModel();
|
||||
const Props = defineProps({
|
||||
type: {
|
||||
type: String,
|
||||
default: 'datetime', // 'date、datetime、time、yearmonth、year、daterange、datetimerange、timerange、yearmonthrange、yearrange'
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请选择'
|
||||
},
|
||||
startPlaceholder: {
|
||||
type: String,
|
||||
default: '请选择'
|
||||
},
|
||||
endPlaceholder: {
|
||||
type: String,
|
||||
default: '请选择'
|
||||
}
|
||||
})
|
||||
const Emits = defineEmits(["change", "update:modelVal"]);
|
||||
const label = ref("");
|
||||
const timeVal = ref(""); // 日期时间
|
||||
const timeVals = ref([]); // 日期时间范围
|
||||
const dateTimeVisible = ref(false); // 日期时间选择显示隐藏
|
||||
let rangeInx = 0; // 范围值的索引
|
||||
watch(() => modelVal.value, (newVal, oldVal) => {
|
||||
if( Props.type.indexOf("range") > -1 ) {
|
||||
timeVals.value = newVal??[];
|
||||
} else {
|
||||
timeVal.value = newVal
|
||||
}
|
||||
}, { immediate: true, deep: true})
|
||||
|
||||
watch(() => Props.type, (newVal, oldVal) => {
|
||||
switch(newVal) {
|
||||
case 'date':
|
||||
label.value = '日期';
|
||||
break
|
||||
case 'daterange':
|
||||
label.value = '日期';
|
||||
break
|
||||
case 'datetimerange':
|
||||
label.value = '日期时间';
|
||||
break
|
||||
case 'datetime':
|
||||
label.value = '日期时间';
|
||||
break
|
||||
case 'time':
|
||||
label.value = '时间';
|
||||
break
|
||||
case 'timerange':
|
||||
label.value = '时间';
|
||||
break
|
||||
case 'year':
|
||||
label.value = '年份';
|
||||
break
|
||||
case 'yearrange':
|
||||
label.value = '年份';
|
||||
break
|
||||
case 'yearmonth':
|
||||
label.value = '年月';
|
||||
break
|
||||
case 'yearmonthrange':
|
||||
label.value = '年月';
|
||||
break
|
||||
}
|
||||
}, { immediate: true})
|
||||
|
||||
const defaultVal = ref([]); // 下拉时间默认值
|
||||
const years = ref([]); //年
|
||||
const nowYear = new Date().getFullYear();
|
||||
// 设置年份数组
|
||||
for (let i = nowYear - 100; i <= nowYear+100; i++) {
|
||||
if(i < 1970) continue;
|
||||
years.value.push(i.toString());
|
||||
}
|
||||
const months = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']; //月
|
||||
const days = ref([]); // 日
|
||||
const hours = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23'];
|
||||
const minutes = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59']
|
||||
|
||||
|
||||
/** 打开日期时间选择
|
||||
* @param { String } key form属性键
|
||||
* @param { String } datetype 时间类型
|
||||
* @param { Number } inx 值在时间范围的索引
|
||||
*/
|
||||
function openTimeSelect(inx=0) {
|
||||
// 设置下拉默认值
|
||||
const data = (Props.type.indexOf("range") > -1)? timeVals.value[inx] :timeVal.value;
|
||||
let now;
|
||||
// 获取当前时间
|
||||
if (Props.type == 'time' || Props.type == 'timerange') {
|
||||
now = data?new Date('2025-01-01 '+data):new Date();
|
||||
} else {
|
||||
now = data?new Date(data):new Date();
|
||||
}
|
||||
// 获取当前年份
|
||||
const currentYear = now.getFullYear();
|
||||
const currentMonth = now.getMonth()+1;
|
||||
const currentDay = now.getDate();
|
||||
const currentHour = now.getHours();
|
||||
const currentMinute = now.getMinutes();
|
||||
// 设置天数数组
|
||||
const dayCount = new Date(currentYear, currentMonth, 0).getDate(); //此月天数
|
||||
days.value = []
|
||||
for (let i = 1; i <= dayCount; i++) {
|
||||
days.value.push(i>9?i.toString():'0'+i);
|
||||
}
|
||||
|
||||
// 设置默认年月日时分
|
||||
setIndex(currentYear, 0, years.value);
|
||||
setIndex(currentMonth, 1, months);
|
||||
setIndex(currentDay, 2, days.value);
|
||||
setIndex(currentHour, 3, hours);
|
||||
setIndex(currentMinute, 4, minutes);
|
||||
|
||||
// 下拉选择显示
|
||||
if(dateTimeVisible.value && rangeInx == inx){
|
||||
dateTimeVisible.value = false;
|
||||
rangeInx = 0;
|
||||
} else {
|
||||
dateTimeVisible.value = false;
|
||||
rangeInx = inx;
|
||||
setTimeout(() => {
|
||||
dateTimeVisible.value = true;
|
||||
}, 60)
|
||||
}
|
||||
}
|
||||
|
||||
// 根据值设置各列索引
|
||||
function setIndex(val, inx, list) {
|
||||
defaultVal.value[inx] = list.findIndex(item => item == val)
|
||||
}
|
||||
|
||||
// 日期时间改变
|
||||
function pickerChange(val) {
|
||||
const Y = years.value[ val.detail.value[0] ];
|
||||
const M = months[ val.detail.value[1] ];
|
||||
const D = days.value[ val.detail.value[2] ];
|
||||
const h = hours[ val.detail.value[3] ];
|
||||
const m = minutes[ val.detail.value[4] ];
|
||||
// 更新天数
|
||||
const dayCount = new Date(Y, M, 0).getDate(); //此月天数
|
||||
if(days.value.length != dayCount){
|
||||
days.value = [];
|
||||
for (let i = 1; i <= dayCount; i++) {
|
||||
days.value.push(i>9?i.toString():'0'+i);
|
||||
}
|
||||
}
|
||||
switch(Props.type) {
|
||||
case 'datetime':
|
||||
timeVal.value = `${Y}-${M}-${D} ${h}:${m}:00`
|
||||
break;
|
||||
case 'datetimerange':
|
||||
timeVals.value[rangeInx] = `${Y}-${M}-${D} ${h}:${m}:00`
|
||||
break;
|
||||
case 'date':
|
||||
timeVal.value = `${Y}-${M}-${D}`
|
||||
break;
|
||||
case 'daterange':
|
||||
timeVals.value[rangeInx] = `${Y}-${M}-${D}`
|
||||
break;
|
||||
case 'time':
|
||||
timeVal.value = `${h}:${m}:00`
|
||||
break;
|
||||
case 'timerange':
|
||||
timeVals.value[rangeInx] = `${h}:${m}:00`
|
||||
break;
|
||||
case 'yearmonth':
|
||||
timeVal.value = `${Y}-${M}`
|
||||
break;
|
||||
case 'yearmonthrange':
|
||||
timeVals.value[rangeInx] = `${Y}-${M}`
|
||||
break;
|
||||
case 'year':
|
||||
timeVal.value = `${Y}`
|
||||
break;
|
||||
case 'yearrange':
|
||||
timeVals.value[rangeInx] = `${Y}`
|
||||
break;
|
||||
}
|
||||
if(Props.type.indexOf('range') > -1){
|
||||
// 根据大小重新排序
|
||||
Emits('change', timeVals.value);
|
||||
Emits("update:modelVal", timeVals.value)
|
||||
} else {
|
||||
Emits('change', timeVal.value);
|
||||
modelVal.value = timeVal.value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
page, view, text, swiper, swiper-item, image, navigator, icon, form, input, button{
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.op-dateTime-picker{
|
||||
.dateTime{
|
||||
width: 100%;
|
||||
padding: 20rpx;
|
||||
.dateTime-input{
|
||||
padding: 20rpx 32rpx;
|
||||
display: flex;
|
||||
.dateTime-label{
|
||||
font-size: 28rpx;
|
||||
line-height: 72rpx;
|
||||
margin-right: 10rpx;
|
||||
color: #364462;
|
||||
}
|
||||
input{
|
||||
flex: 1;
|
||||
height: 72rpx;
|
||||
background-color: rgb(249, 249, 249);
|
||||
border-radius: 8rpx;
|
||||
padding: 0 10px;
|
||||
color: rgb(96, 98, 102);
|
||||
font-size: 14px;
|
||||
position: relative;
|
||||
&::after{
|
||||
content: '';
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pickerView{
|
||||
width: 100%;
|
||||
height: 350rpx;
|
||||
background-color: #f2f2f2;
|
||||
:deep(.pickerViewColumn){
|
||||
height: 70rpx;
|
||||
}
|
||||
picker-view-column{
|
||||
flex: 0;
|
||||
.item{
|
||||
line-height: 70rpx;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.show{
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
304
components/op-drop-down/components/op-drop-down/op-drop-down.vue
Normal file
304
components/op-drop-down/components/op-drop-down/op-drop-down.vue
Normal file
@@ -0,0 +1,304 @@
|
||||
<template>
|
||||
<view class="drop-down-container">
|
||||
<view class="drop-down-select">
|
||||
<!-- 下拉按钮 -->
|
||||
<view class="select-up">
|
||||
<template v-for="(item, index) in newOption" :key="index">
|
||||
<view class="select-button" @click="openMenu(index)">
|
||||
<text :class="{active: item.menuVisible}">{{item.newTitle??item.title}}</text>
|
||||
<image v-if="item.menuVisible" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAOCAYAAAAi2ky3AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAC3SURBVHgBpc9NDoIwEAXgmWI07jhCPYzGJZ5Aj4Iro5fgKHokFv5EQlooIW3aYVoS3gbSTifvA0hk/3hfDvdPkZrD2OXx9pMqg2c/ljffze5VYs3NitiiVqiy/0gAna+3/yo2yy4yJIHibA9QFzHiJM2RTBtvvOaIk40cKQxPJIsIKQxD9Gg8iTwjRK8RTwpDiXZRkkRK+cSBNp9Etlni0Gg+KYwjoiEhZBUsiVan1fhzhQVBQNkBj+1WDGeu7GQAAAAASUVORK5CYII=" ></image>
|
||||
<image v-else src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAOCAYAAAAi2ky3AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACtSURBVHgBpZNNDsIgEEaBGNYugVN5A+0NPIKeRD1BeyNnB8ueAJxprMEE6LR9yYTh7wtvgbTWXqWUR7GDGOP7gCNg9WIfF+W9H7AZxHaeIYSXok5r3eEwipWklAC17tRPQQAw4mInVoJ3bvga+AURGxQnpXmi8h2uYq5UDOIq5krFIIKh+KdUDSJqiiWlZlBNsaTEwjnXY6VvPVpnVWtzVmwpscFPfTLGnJfOfQDwZHGVR0KC2QAAAABJRU5ErkJggg==" ></image>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
<!-- 下拉选项 -->
|
||||
<view class="select-down">
|
||||
<template v-for="(item, index) in newOption" :key="index">
|
||||
<view v-if="item.menuVisible" class="select-menu">
|
||||
<!-- 联级 -->
|
||||
<Op-Cascader v-if="item.type=='cascader'" v-model="form[newOption[index].key]" :option="item.option" :props="item.props" :iconShow="true" maxHeight="600rpx"></Op-Cascader>
|
||||
<!-- 下拉选择 -->
|
||||
<view class="select" v-if="item.type == 'select'">
|
||||
<view class="label"
|
||||
v-for="(itm, inx) in item.option" :key="inx"
|
||||
:class="{ active: itm.value == form[item.key]}"
|
||||
@click="select(itm.value, itm, inx, index)"
|
||||
>
|
||||
{{itm.label}}
|
||||
</view>
|
||||
</view>
|
||||
<!-- 日期时间选择 -->
|
||||
<Op-DateTime-Picker v-if="['date','time','yearmonth','year','datetime','daterange','timerange','yearmonthrange','yearrange','datetimerange'].includes(item.type)" v-model="form[newOption[index].key]" :type="item.type" :placeholder="item.placeholder" :startPlaceholder="item.startPlaceholder" :endPlaceholder="item.endPlaceholder"></Op-DateTime-Picker>
|
||||
|
||||
<!-- #ifdef H5 || APP-PLUS -->
|
||||
<slot v-if="item.type == 'custom'" :name="newOption[index].key"></slot>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<slot v-if="item.type == 'custom'" name="custom-{{index}}"></slot>
|
||||
<!-- #endif -->
|
||||
<!-- 底部确认按钮 -->
|
||||
<view class="drop-down-button">
|
||||
<view @click="reset(index)">重置</view>
|
||||
<view @click="submit(index)">确定</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
<view class="drop-down-modal" v-if="modalShow" @click="closeModal"></view>
|
||||
</view>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref, defineProps, watch, defineEmits } from 'vue';
|
||||
import OpCascader from '@/components/op-drop-down/components/op-cascader/op-cascader.vue';
|
||||
import OpDateTimePicker from '@/components/op-drop-down/components/op-dateTime-picker/op-dateTime-picker.vue';
|
||||
const form = reactive({});
|
||||
const Props = defineProps({
|
||||
defaultValue: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
option: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
closeOnClickModal:{ // 是否点击模态窗关闭
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
const Emits = defineEmits(['update:modelValue', "submit", "reset", "change" ]);
|
||||
const newOption = ref([]); // 所有选项
|
||||
const modalShow = ref(false); // 模态框
|
||||
watch(() => Props.defaultValue, (newVal, oldVal) => {
|
||||
if(newVal){
|
||||
for(let k in newVal){
|
||||
form[k] = newVal[k];
|
||||
}
|
||||
}
|
||||
}, { deep: true, immediate: true })
|
||||
|
||||
watch(() => Props.option, (newVal, oldVal) => {
|
||||
if(newVal){
|
||||
newOption.value = JSON.parse(JSON.stringify(newVal));
|
||||
}
|
||||
}, { deep: true, immediate: true })
|
||||
|
||||
|
||||
/** 展开菜单 */
|
||||
function openMenu(inx) {
|
||||
if(newOption.value[inx].menuVisible){
|
||||
newOption.value[inx].menuVisible = false;
|
||||
modalShow.value = false;
|
||||
} else {
|
||||
newOption.value.forEach((item, index) => {
|
||||
item.menuVisible = index == inx
|
||||
})
|
||||
modalShow.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** select菜单选择
|
||||
* @param { String | Number } val 选中值
|
||||
* @param { Object } row 选中行
|
||||
* @param { Number } inx 选中行索引
|
||||
* @param { Number } parentInx 选中行父级索引
|
||||
*/
|
||||
function select(val, row, inx, parentInx) {
|
||||
form[newOption.value[parentInx].key] = val;
|
||||
}
|
||||
|
||||
|
||||
// 重置
|
||||
function reset(inx) {
|
||||
// 初始话默认值,联级选择需要设置为[],防止双向数据绑定失效
|
||||
if(newOption.value[inx].type == 'cascader' || newOption.value[inx].type.indexOf('range') > -1){
|
||||
form[newOption.value[inx].key] = [];
|
||||
} else {
|
||||
form[newOption.value[inx].key] = undefined;
|
||||
}
|
||||
newOption.value[inx].menuVisible = false;
|
||||
modalShow.value = false;
|
||||
const data = JSON.parse(JSON.stringify(form));
|
||||
Emits("reset", data);
|
||||
Emits("change", data);
|
||||
}
|
||||
|
||||
// 确认提交
|
||||
function submit(inx) {
|
||||
newOption.value[inx].menuVisible = false;
|
||||
modalShow.value = false;
|
||||
let data = JSON.parse(JSON.stringify(form));
|
||||
if(newOption.value[inx].type.indexOf('range') > -1 ){
|
||||
const key = newOption.value[inx].key;
|
||||
if(data[key] && data[key][0] && data[key][1] ){
|
||||
data[key] = againSort(data[key], newOption.value[inx].type)
|
||||
}
|
||||
}
|
||||
Emits("submit", data);
|
||||
if(JSON.stringify(Props.value) != JSON.stringify(form)){
|
||||
Emits("change", data);
|
||||
}
|
||||
}
|
||||
// 重新排序
|
||||
function againSort(arr, type) {
|
||||
if(!arr[0] || !arr[1]) return arr;
|
||||
let start = 0;
|
||||
let end = 0;
|
||||
if(type.indexOf('date') > -1 && type.indexOf('year') > -1){
|
||||
start = new Date(arr[0]).getTime();
|
||||
end = new Date(arr[1]).getTime();
|
||||
} else if (type == 'timerange') {
|
||||
start = arr[0].split(":").join("");
|
||||
end = arr[1].split(":").join("");
|
||||
}
|
||||
return end > start? arr: [ arr[1], arr[0] ]
|
||||
}
|
||||
|
||||
// 关闭模态窗
|
||||
function closeModal() {
|
||||
if(!Props.closeOnClickModal) return
|
||||
newOption.value.forEach(item => {
|
||||
item.menuVisible = false;
|
||||
})
|
||||
modalShow.value = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
page, view, text, swiper, swiper-item, image, navigator, icon, form, input, button{
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.drop-down-container{
|
||||
flex-shrink: 0;
|
||||
background-color: #fff;
|
||||
position: relative;
|
||||
.drop-down-select{
|
||||
width: 100%;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
.select-up{
|
||||
width: 100%;
|
||||
height: 92rpx;
|
||||
display: flex;
|
||||
.select-button{
|
||||
flex: 1;
|
||||
padding: 24rpx 10rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
text{
|
||||
font-size: 30rpx;
|
||||
line-height: 44rpx;
|
||||
color: #1A1A1A;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
&.active{
|
||||
color: #468AF7;
|
||||
}
|
||||
}
|
||||
image{
|
||||
flex-shrink: 0;
|
||||
width: 18rpx;
|
||||
height: 14rpx;
|
||||
margin-left: 22rpx;
|
||||
}
|
||||
&.active{
|
||||
text{
|
||||
color: #468AF7;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.select-down{
|
||||
width: 100%;
|
||||
border-top: 1rpx solid rgba(0,0,0,0.1);
|
||||
background-color: #fff;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 92rpx;
|
||||
.select{
|
||||
width: 100%;
|
||||
.label{
|
||||
text-align: center;
|
||||
color: #364462;
|
||||
font-size: 32rpx;
|
||||
line-height: 92rpx;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
padding: 0 10rpx;
|
||||
&.active{
|
||||
color: #468AF7;
|
||||
}
|
||||
}
|
||||
}
|
||||
.dateTime{
|
||||
width: 100%;
|
||||
padding: 20rpx;
|
||||
.dateTime-input{
|
||||
padding: 20rpx 32rpx;
|
||||
display: flex;
|
||||
.dateTime-label{
|
||||
font-size: 28rpx;
|
||||
line-height: 72rpx;
|
||||
margin-right: 10rpx;
|
||||
color: #364462;
|
||||
}
|
||||
input{
|
||||
flex: 1;
|
||||
height: 72rpx;
|
||||
background-color: rgb(249, 249, 249);
|
||||
border-radius: 8rpx;
|
||||
padding: 0 10px;
|
||||
color: rgb(96, 98, 102);
|
||||
font-size: 14px;
|
||||
position: relative;
|
||||
&::after{
|
||||
content: '';
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.drop-down-button{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
view{
|
||||
flex: 1;
|
||||
height: 88rpx;
|
||||
font-size: 32rpx;
|
||||
line-height: 88rpx;
|
||||
text-align: center;
|
||||
font-size: rgba(0,0,0,0.9);
|
||||
&:nth-of-type(1){
|
||||
border-top: 1rpx solid rgba(0,0,0,0.1);
|
||||
}
|
||||
&:nth-of-type(2){
|
||||
background-color: #468AF7;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.drop-down-modal{
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
background-color: rgba(0,0,0,0.5);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
88
components/op-drop-down/package.json
Normal file
88
components/op-drop-down/package.json
Normal file
@@ -0,0 +1,88 @@
|
||||
{
|
||||
"id": "op-drop-down",
|
||||
"displayName": "op-drop-down",
|
||||
"version": "1.1.1",
|
||||
"description": "多功能下拉筛选,支持tree联机筛选、时间范围筛选、数组筛选、自定义筛选菜单",
|
||||
"keywords": [
|
||||
"drop-down",
|
||||
"datetimerange",
|
||||
"cascader",
|
||||
"自定义",
|
||||
"下拉筛选"
|
||||
],
|
||||
"repository": "",
|
||||
"engines": {
|
||||
"HBuilderX": "^3.1.0"
|
||||
},
|
||||
"dcloudext": {
|
||||
"type": "component-vue",
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "插件不采集任何数据",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": ""
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y",
|
||||
"alipay": "y"
|
||||
},
|
||||
"client": {
|
||||
"Vue": {
|
||||
"vue2": "u",
|
||||
"vue3": "y"
|
||||
},
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "u",
|
||||
"app-uvue": "u",
|
||||
"app-harmony": "u"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "y",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "u",
|
||||
"百度": "u",
|
||||
"字节跳动": "u",
|
||||
"QQ": "y",
|
||||
"钉钉": "u",
|
||||
"快手": "u",
|
||||
"飞书": "u",
|
||||
"京东": "u"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "u",
|
||||
"联盟": "u"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
167
components/op-drop-down/readme.md
Normal file
167
components/op-drop-down/readme.md
Normal file
@@ -0,0 +1,167 @@
|
||||
# op-drop-down
|
||||
# 前端UI下拉选择组件,
|
||||
|
||||
### 使用方式
|
||||
|
||||
```html
|
||||
<Op-Drop-Down :defaultValue="form" :option="paramOptions" :closeOnClickModal="true" @change="onChange" @reset="reset">
|
||||
<template #customKey>
|
||||
<button>按钮1</button>
|
||||
<button>按钮2</button>
|
||||
<button>按钮3</button>
|
||||
<button>按钮4</button>
|
||||
</template>
|
||||
</Op-Drop-Down>
|
||||
```
|
||||
```javascript
|
||||
import OpDropDown from '@/uni_modules/op-drop-down/components/op-drop-down/op-drop-down.vue';
|
||||
|
||||
export default {
|
||||
components: { OpDropDown },
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
type: [],
|
||||
status: '',
|
||||
time: '',
|
||||
dateTimeRange: [],
|
||||
customKey: ''
|
||||
},
|
||||
paramOptions: [
|
||||
{
|
||||
title: '分类',
|
||||
key: 'type',
|
||||
type: 'cascader',
|
||||
props: { label: 'label', value: 'value', children: 'children', disabled: 'disabled'},
|
||||
option: [
|
||||
{
|
||||
label: '标题1',
|
||||
value: '1',
|
||||
children: [
|
||||
{
|
||||
label: '标题1-1',
|
||||
value: '1-1',
|
||||
children: [
|
||||
{ label: '标题1-1-1', value: '1-1-1' },
|
||||
{ label: '标题1-1-2', value: '1-1-2' },
|
||||
{ label: '标题1-1-3', value: '1-1-3', disabled: true },
|
||||
{ label: '标题1-1-4', value: '1-1-4', disabled: true },
|
||||
{ label: '标题1-1-5', value: '1-1-5' },
|
||||
{ label: '标题1-1-6', value: '1-1-6' }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '标题1-2',
|
||||
value: '1-2',
|
||||
children: [
|
||||
{ label: '标题1-2-1', value: '1-2-1' },
|
||||
{ label: '标题1-2-2', value: '1-2-2' }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '标题2',
|
||||
value: '2',
|
||||
children: [
|
||||
{
|
||||
label: '标题2-1',
|
||||
value: '2-1',
|
||||
children: [
|
||||
{ label: '标题2-1-1', value: '2-1-1' },
|
||||
{ label: '标题2-1-2', value: '2-1-2' }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '标题2-2',
|
||||
value: '2-2',
|
||||
children: [
|
||||
{ label: '标题2-2-1', value: '2-2-1' },
|
||||
{ label: '标题2-2-2', value: '2-2-2' }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '标题3',
|
||||
value: '3',
|
||||
},
|
||||
{
|
||||
label: '标题4',
|
||||
value: '4',
|
||||
},
|
||||
{
|
||||
label: '标题5',
|
||||
value: '5',
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
type: 'select',
|
||||
option: [
|
||||
{ label: '在线', value: 'online'},
|
||||
{ label: '离线', value: 'offline'},
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '时间',
|
||||
key: 'time',
|
||||
type: 'time',
|
||||
placeholder: '请选择',
|
||||
},
|
||||
{
|
||||
title: '日期范围',
|
||||
key: 'dateTimeRange',
|
||||
type: 'datetimerange',
|
||||
startPlaceholder: '请选择',
|
||||
endPlaceholder: '请选择',
|
||||
},
|
||||
{
|
||||
title: '自定义',
|
||||
key: 'customKey',
|
||||
type: 'custom',
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
onChange(val) {
|
||||
this.form = val
|
||||
console.log(val)
|
||||
},
|
||||
reset(val) {
|
||||
this.form = val
|
||||
console.log(val)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
###组件的属性说明如下:
|
||||
| 属性 | 类型 | 默认值 | 必填 | 说明 |
|
||||
| ---------------- | ------- | ------- | ---- | ------------------------------ |
|
||||
| defaultValue | Object | {} | 是 | 设置整个下拉的默认键值对 |
|
||||
| option | Array | [] | 是 | 下拉菜单配置的数据 |
|
||||
| closeOnClickModal | Boolean | true | 否 | 点击模态窗是否关闭下拉 |
|
||||
|
||||
####option参数说明:
|
||||
| 属性 | 类型 | 默认值 | 必填 | 说明 |
|
||||
| ---------------- | ------- | ------- | ---- | ------------------------------ |
|
||||
| title | String | | 是 | 属性名,显示在页面上 |
|
||||
| key | String | | 是 | 与defaultValue对应的键 |
|
||||
| type | String | 可选cascader、select、date、time、yearmonth、year、datetime、daterange、timerange、yearmonthrange、yearrange、datetimerange、custom | 是 | 下拉类型 |
|
||||
| props | Object | { label: label, value: value, children: children } | 否 | 只针对联级下拉选择项cascader,自定义节点 label、value、options 的字段 |
|
||||
| placeholder | String | | 否 | 时间选择占位文本 |
|
||||
| startPlaceholder | String | | 否 | 时间范围选择占位文本 |
|
||||
| endPlaceholder | String | | 否 | 时间范围选择占位文本 |
|
||||
|
||||
###事件
|
||||
| 事件名称 | 回调参数 | 说明 |
|
||||
| --------- | -------------------- | ------------------------------------------------------------ |
|
||||
| change | (data) => void | 改变事件,data为当前操作后的数据 |
|
||||
| reset | (data) => void | 重置其中一个选中数据,data为当前操作后的数据 |
|
||||
Reference in New Issue
Block a user