首页 分类列表
This commit is contained in:
@@ -14,4 +14,7 @@ export default {
|
|||||||
home(data) { //首页上半部分
|
home(data) { //首页上半部分
|
||||||
return uni.api.post("/home", data);
|
return uni.api.post("/home", data);
|
||||||
},
|
},
|
||||||
|
locationdistrict(data) { //获取行政区域(区,街道)
|
||||||
|
return uni.api.get("/location/district", data);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,9 @@ const debug = process.env.NODE_ENV == 'development' ? true : false;
|
|||||||
const proxyApi = "/api"
|
const proxyApi = "/api"
|
||||||
// #endif
|
// #endif
|
||||||
// #ifdef MP-WEIXIN || APP
|
// #ifdef MP-WEIXIN || APP
|
||||||
const proxyApi = 'http://101.37.12.135:9889/cashierService' // 线上
|
// const proxyApi = 'http://192.168.2.133:9889/cashierService' // 王伟
|
||||||
|
// const proxyApi = 'http://101.37.12.135:9889/cashierService' // 帆哥
|
||||||
|
const proxyApi = 'https://wxcashiertest.sxczgkj.cn/cashierService'
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<view class="therecontent_box_itembox">
|
<view class="therecontent_box_itembox">
|
||||||
<view class="therecontent_box_itembox_item flex-between" v-for="(item,index) in todayList.todayList"
|
<view class="therecontent_box_itembox_item flex-between" v-for="(item,index) in todayList.todayList"
|
||||||
:key="item">
|
:key="item">
|
||||||
<image src="@/static/avatar.png" mode="aspectFill"></image>
|
<image :src="item.image" mode="aspectFill"></image>
|
||||||
<view class="therecontent_box_itembox_itemview">
|
<view class="therecontent_box_itembox_itemview">
|
||||||
<view class="therecontent_box_itembox_itemviewone">
|
<view class="therecontent_box_itembox_itemviewone">
|
||||||
{{item.productName}}
|
{{item.productName}}
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="therecontent_box_itembox">
|
<view class="therecontent_box_itembox">
|
||||||
<view class="therecontent_box_itembox_item flex-between" v-for="(item,index) in salesList.hotList" :key="item">
|
<view class="therecontent_box_itembox_item flex-between" v-for="(item,index) in salesList.hotList" :key="item">
|
||||||
<image src="@/static/avatar.png" mode="aspectFill"></image>
|
<image :src="item.image" mode="aspectFill"></image>
|
||||||
<view class="therecontent_box_itembox_itemview">
|
<view class="therecontent_box_itembox_itemview">
|
||||||
<view class="therecontent_box_itembox_itemviewone flex-start">
|
<view class="therecontent_box_itembox_itemviewone flex-start">
|
||||||
<view class="therecontent_box_itembox_itemviewoneafter">
|
<view class="therecontent_box_itembox_itemviewoneafter">
|
||||||
|
|||||||
@@ -49,10 +49,12 @@
|
|||||||
<!-- 今日上线 -->
|
<!-- 今日上线 -->
|
||||||
<todaylist :todayList='hometoplist.todayList' :salesList='hometoplist.salesList'></todaylist>
|
<todaylist :todayList='hometoplist.todayList' :salesList='hometoplist.salesList'></todaylist>
|
||||||
<!-- 类目 -->
|
<!-- 类目 -->
|
||||||
<view class="fourcontent flex-between" @click="viewHistory">
|
<view class="fourcontent flex-between">
|
||||||
<view class="fourcontent_item flex-start" v-for="(item,index) in hometoplist.menu" :key="index">
|
<view class="fourcontent_item flex-start" v-for="(item,index) in hometoplist.menu" :key="index"
|
||||||
|
@click="viewHistory(item)">
|
||||||
<text>{{item.name}}</text>
|
<text>{{item.name}}</text>
|
||||||
<u-icon style="margin-left: 8rpx;" name="arrow-down-fill" color="#333333" size="16"></u-icon>
|
<u-icon v-if="item.isChild" style="margin-left: 8rpx;" name="arrow-down-fill" color="#333333"
|
||||||
|
size="16"></u-icon>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@@ -172,10 +174,35 @@
|
|||||||
<!-- 吸顶 -->
|
<!-- 吸顶 -->
|
||||||
<view class="fourcontent flex-between" style="padding: 28rpx 0 28rpx 28rpx">
|
<view class="fourcontent flex-between" style="padding: 28rpx 0 28rpx 28rpx">
|
||||||
<view class="fourcontent_item flex-start" v-for="(item,index) in hometoplist.menu"
|
<view class="fourcontent_item flex-start" v-for="(item,index) in hometoplist.menu"
|
||||||
:key="index">
|
:key="index" @click="viewHistory(item)">
|
||||||
<text>{{item.name}}</text>
|
<text>{{item.name}}</text>
|
||||||
<u-icon style="margin-left: 8rpx;" name="arrow-down-fill" color="#333333"
|
<u-icon v-if="item.isChild" style="margin-left: 8rpx;" name="arrow-down-fill"
|
||||||
size="16"></u-icon>
|
color="#333333" size="16"></u-icon>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 显示下拉字段 -->
|
||||||
|
<view class="sixcontent" v-if="clickhometoplistmenulist.detail">
|
||||||
|
<view class="sixcontentitemP flex-colum-start">
|
||||||
|
<view class="sixcontentitemP_item"
|
||||||
|
:class="index == clickdetailindex ?'sixcontentitemP_itemactive':''"
|
||||||
|
v-for="(item,index) in clickhometoplistmenulist.detail" :key="index"
|
||||||
|
@click="clickdetail(item,index)">
|
||||||
|
{{item.label}}
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="sixcontent" v-if="clickhometoplistmenulist.districts">
|
||||||
|
<view class="sixcontentitemP flex-start">
|
||||||
|
<view class="sixcontentitemP_itembox flex-colum-start">
|
||||||
|
<view class="sixcontentitemP_itemone"
|
||||||
|
:class="index == clickdetailindex ?'sixcontentitemP_itemactive':''"
|
||||||
|
v-for="(item,index) in clickhometoplistmenulist.districts" :key="index"
|
||||||
|
@click="clickdetail(item,index)">
|
||||||
|
{{item.name}}
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -205,12 +232,14 @@
|
|||||||
keyword: '',
|
keyword: '',
|
||||||
current: 0,
|
current: 0,
|
||||||
opacity: false,
|
opacity: false,
|
||||||
showproductlist: false, //弹成
|
showproductlist: true, //弹成
|
||||||
|
clickdetailindex: 0, //默认下拉选项第一个
|
||||||
hometoplist: { //上面数据
|
hometoplist: { //上面数据
|
||||||
carousel: [],
|
carousel: [],
|
||||||
district: []
|
district: []
|
||||||
},
|
},
|
||||||
homelist: [], //下面数据
|
homelist: [], //下面数据
|
||||||
|
clickhometoplistmenulist: {}, //下拉点击的数据
|
||||||
form: {
|
form: {
|
||||||
address: '', //地址
|
address: '', //地址
|
||||||
type: '', //品类
|
type: '', //品类
|
||||||
@@ -219,7 +248,6 @@
|
|||||||
page: 1, //页数
|
page: 1, //页数
|
||||||
size: 10, //页容量
|
size: 10, //页容量
|
||||||
status: 'loadmore'
|
status: 'loadmore'
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -242,10 +270,14 @@
|
|||||||
return this.$store.getters.is_BarHeight
|
return this.$store.getters.is_BarHeight
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
onLoad() {
|
async onLoad() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.GetTop()
|
this.GetTop()
|
||||||
}, 1000)
|
}, 1000)
|
||||||
|
let res = await this.apix.locationdistrict({
|
||||||
|
keywords: '西安市'
|
||||||
|
})
|
||||||
|
this.clickhometoplistmenulist = res.data[0].districts
|
||||||
},
|
},
|
||||||
onReachBottom() {
|
onReachBottom() {
|
||||||
this.onLoadhome()
|
this.onLoadhome()
|
||||||
@@ -315,12 +347,30 @@
|
|||||||
//TODO handle the exception
|
//TODO handle the exception
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async viewHistory() {
|
// 点击元素到指定位置
|
||||||
this.showproductlist = true
|
async viewHistory(item) {
|
||||||
|
if (item.dictName == 'allCity') {
|
||||||
|
let res = await this.apix.locationdistrict({
|
||||||
|
keywords: '西安市'
|
||||||
|
})
|
||||||
|
this.clickhometoplistmenulist = res.data[0]
|
||||||
|
} else {
|
||||||
|
this.clickhometoplistmenulist = item
|
||||||
|
}
|
||||||
uni.pageScrollTo({
|
uni.pageScrollTo({
|
||||||
scrollTop: this.Topdistance + 1,
|
scrollTop: this.Topdistance + 1,
|
||||||
duration: 300
|
duration: 300
|
||||||
});
|
});
|
||||||
|
if (item.isChild) {
|
||||||
|
this.showproductlist = true
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 选择元素的指定选项
|
||||||
|
clickdetail(item, index) {
|
||||||
|
this.clickdetailindex = index
|
||||||
|
this.showproductlist = false
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -466,6 +516,48 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sixcontent {
|
||||||
|
.sixcontentitemP {
|
||||||
|
padding: 0 32rpx 28rpx 32rpx;
|
||||||
|
max-height: 600rpx;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
.sixcontentitemP_itembox {
|
||||||
|
.sixcontentitemP_itemone {
|
||||||
|
flex: 1;
|
||||||
|
margin-top: 16rpx;
|
||||||
|
font-family: Source Han Sans CN, Source Han Sans CN;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sixcontentitemP_itemone:nth-child(1) {
|
||||||
|
margin-top: 0rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sixcontentitemP_item:nth-child(1) {
|
||||||
|
margin-top: 0rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sixcontentitemP_item {
|
||||||
|
margin-top: 16rpx;
|
||||||
|
font-family: Source Han Sans CN, Source Han Sans CN;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sixcontentitemP_itemactive {
|
||||||
|
font-family: Source Han Sans CN, Source Han Sans CN;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.fivecontent {
|
.fivecontent {
|
||||||
padding: 0 28rpx;
|
padding: 0 28rpx;
|
||||||
|
|
||||||
|
|||||||
13
uni_modules/le-dropdown/changelog.md
Normal file
13
uni_modules/le-dropdown/changelog.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
## 1.0.4(2023-06-04)
|
||||||
|
1.更新层级点击不了问题;
|
||||||
|
2.增加吸顶属性配置;
|
||||||
|
3.cell类型选中建议增加对号图标;
|
||||||
|
4.完善文档;
|
||||||
|
## 1.0.3(2023-04-15)
|
||||||
|
更新选项增加箭头交互
|
||||||
|
## 1.0.2(2023-04-14)
|
||||||
|
更新示例
|
||||||
|
## 1.0.1(2023-04-09)
|
||||||
|
更新版本标签
|
||||||
|
## 1.0.0(2023-04-09)
|
||||||
|
第一个版本
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
<template>
|
||||||
|
<view class="picker-view">
|
||||||
|
<scroll-view
|
||||||
|
v-for="(num,index) in colNum"
|
||||||
|
:key="index"
|
||||||
|
:style="{
|
||||||
|
width:`${1/colNum*100}%`,
|
||||||
|
height:'100%',
|
||||||
|
backgroundColor:index===0?'#F6F6F6':'#FFFFFF'
|
||||||
|
}"
|
||||||
|
scroll-y>
|
||||||
|
<view
|
||||||
|
:class="['picker-view-item',modelValue[index]==item.value&&'picker-view-item-active']"
|
||||||
|
v-for="(item,indexs) in colList[index]"
|
||||||
|
:key="indexs"
|
||||||
|
@click="onSelect(index,item,indexs)"
|
||||||
|
>
|
||||||
|
{{item.label}}
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
ref,
|
||||||
|
computed
|
||||||
|
} from "vue";
|
||||||
|
const props = defineProps({
|
||||||
|
// 双向绑定
|
||||||
|
modelValue: {
|
||||||
|
type: Array,
|
||||||
|
default: []
|
||||||
|
},
|
||||||
|
// 展示的列数
|
||||||
|
colNum: {
|
||||||
|
type: Number,
|
||||||
|
default: 1
|
||||||
|
},
|
||||||
|
// options 数据
|
||||||
|
options: {
|
||||||
|
type: Array,
|
||||||
|
default: []
|
||||||
|
},
|
||||||
|
// 自定义节点 label、value、children 的字段
|
||||||
|
fieldNames: {
|
||||||
|
type: Object,
|
||||||
|
default: ()=>{
|
||||||
|
return {
|
||||||
|
label: 'label',
|
||||||
|
value: 'value',
|
||||||
|
children: 'children',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const emits = defineEmits(["update:modelValue"])
|
||||||
|
const colList = computed(() => {
|
||||||
|
const arr = [];
|
||||||
|
let option = props.options;
|
||||||
|
for(let i=0;i<props.colNum;i++){
|
||||||
|
if ((props.modelValue[i] != undefined&&option)||(props.modelValue[i-1]&&option)||(i===0&&option)) {
|
||||||
|
arr.push(funOptions(option))
|
||||||
|
const index = option?.findIndex(item=>item[props.fieldNames.value]==props.modelValue[i])
|
||||||
|
option = (option[index]&&option[index]?.[props.fieldNames.children])||[];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
})
|
||||||
|
const funOptions = (data) => {
|
||||||
|
return data.map((item) => {
|
||||||
|
return {
|
||||||
|
label: item[props.fieldNames.label],
|
||||||
|
value: item[props.fieldNames.value],
|
||||||
|
children:item[props.fieldNames.children]||[]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const onSelect = (index,item,indexs) => {
|
||||||
|
const modelValue = JSON.parse(JSON.stringify(props.modelValue))
|
||||||
|
if(modelValue[index]!=item.value){
|
||||||
|
modelValue[index] = item.value;
|
||||||
|
let option = item[props.fieldNames.children]||[]
|
||||||
|
for(let i=index+1;i<props.colNum;i++){
|
||||||
|
if(option[0]){
|
||||||
|
modelValue[i] = option[0][props.fieldNames.value]
|
||||||
|
option = option[0]?.[props.fieldNames.children]||[]
|
||||||
|
}else if(modelValue[i]){
|
||||||
|
modelValue.splice(i,modelValue.length)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emits("update:modelValue",modelValue)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.picker-view {
|
||||||
|
width: 100%;
|
||||||
|
height: 600rpx;
|
||||||
|
display: flex;
|
||||||
|
.picker-view-item{
|
||||||
|
padding: 30rpx 0;
|
||||||
|
text-align: center;
|
||||||
|
font-size:24rpx;
|
||||||
|
color:#333333;
|
||||||
|
}
|
||||||
|
.picker-view-item-active{
|
||||||
|
color:var(--dropdownThemeColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
603
uni_modules/le-dropdown/components/le-dropdown/le-dropdown.vue
Normal file
603
uni_modules/le-dropdown/components/le-dropdown/le-dropdown.vue
Normal file
@@ -0,0 +1,603 @@
|
|||||||
|
<template>
|
||||||
|
<view
|
||||||
|
:class="['le-dropdown',isCeiling&&'le-dropdown-ceiling']"
|
||||||
|
:style="`--dropdownThemeColor:${themeColor};--dropdownThemeColorRgb:${hexToRgb(themeColor)}`">
|
||||||
|
<!-- 导航 -->
|
||||||
|
<view class="le-dropdown-menu">
|
||||||
|
<view class="le-dropdown-menu-item" v-for="(item, index) in menuList" :key="index"
|
||||||
|
@tap.stop="menuClick(index)">
|
||||||
|
<view class="le-flex">
|
||||||
|
<text class="le-dropdown-menu-item-text" :style="{
|
||||||
|
color: index === current ? themeColor : inactiveColor
|
||||||
|
}">{{item.title}}</text>
|
||||||
|
<view v-if="item.type==='sort'"
|
||||||
|
:class="['le-dropdown-menu-item-arrow',item.value==='asc'&&'le-dropdown-menu-item-arrow_top',item.value==='desc'&&'le-dropdown-menu-item-arrow_bottom']">
|
||||||
|
</view>
|
||||||
|
<view v-if="item.type!=='sort'"
|
||||||
|
:class="['le-dropdown-menu-item-basicarrow',index === current&&'le-dropdown-menu-item-basicarrow_rotate']">
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 展示的内容 -->
|
||||||
|
<view class="le-dropdown-content" :style="[
|
||||||
|
{
|
||||||
|
transition: `opacity ${duration / 1000}s linear`,
|
||||||
|
top:'auto',
|
||||||
|
bottom:`calc(100vh - ${contentHeight + windowTop}px)`,
|
||||||
|
height:`calc(100vh - ${contentHeight + windowTop}px)`
|
||||||
|
},
|
||||||
|
contentStyle
|
||||||
|
]" @tap="close">
|
||||||
|
<view ref="leDropdownContentPopupRef" class="le-dropdown-content-popup" :style="[popupStyle]"
|
||||||
|
@tap.stop.prevent>
|
||||||
|
<block v-for="(item,index) in menuList" :key="index">
|
||||||
|
<!-- 单选列表 -->
|
||||||
|
<view class="le-dropdown-popup-content le-dropdown-cell"
|
||||||
|
v-if="item.type==='cell'&&index === current">
|
||||||
|
<view :class="['le-dropdown-cell-item',item.value===sItem.value&&'le-dropdown-cell-active']"
|
||||||
|
v-for="(sItem,sIndex) in item.options" :key="sIndex" @click="onSelectCell(sItem,index)">
|
||||||
|
<view class="le-dropdown-cell-active-text">{{sItem.label}}</view>
|
||||||
|
<view v-show="item.value===sItem.value" class="le-dropdown-cell-active-icon"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 级联动选择 -->
|
||||||
|
<view class="le-dropdown-popup-content le-dropdown-picker"
|
||||||
|
v-if="item.type==='picker'&&index === current">
|
||||||
|
<le-dropdown-picker v-model="item.value" v-bind="item.componentProps">
|
||||||
|
</le-dropdown-picker>
|
||||||
|
<view class="le-dropdown-footer">
|
||||||
|
<view class="le-dropdown-confirm" @click="onFilterConfirm(item,index)">
|
||||||
|
{{item.confirmText||'确定'}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 筛选 -->
|
||||||
|
<view class="le-dropdown-popup-content le-dropdown-filter"
|
||||||
|
v-if="item.type==='filter'&&index === current">
|
||||||
|
<view class="le-dropdown-filter-item" v-for="(sItem,sIndex) in item.children" :key="sIndex">
|
||||||
|
<view class="le-dropdown-filter-title">
|
||||||
|
{{sItem.title}}
|
||||||
|
<text class="le-dropdown-filter-subtitle"
|
||||||
|
v-if="sItem.type==='slider'">{{sItem.value}}{{sItem.suffix}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="le-dropdown-filter-content">
|
||||||
|
<!-- 单选类型 -->
|
||||||
|
<block v-if="sItem.type==='radio'">
|
||||||
|
<view v-for="(ssItem,ssIndex) in sItem.options"
|
||||||
|
:class="['le-dropdown-filter-box',sItem.value===ssItem.value&&'le-dropdown-filter-box-active']"
|
||||||
|
:key="ssIndex" @click="onRadioFilter(sIndex,ssItem,index)">
|
||||||
|
{{ssItem.label}}
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
<!-- 多选类型 -->
|
||||||
|
<block v-else-if="sItem.type==='checkbox'">
|
||||||
|
<view v-for="(ssItem,ssIndex) in sItem.options"
|
||||||
|
:class="['le-dropdown-filter-box',sItem.value.includes(ssItem.value)&&'le-dropdown-filter-box-active']"
|
||||||
|
:key="ssIndex" @click="onCheckboxFilter(sIndex,ssItem,index)">
|
||||||
|
{{ssItem.label}}
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
<!-- 滑块类型 -->
|
||||||
|
<block v-else-if="sItem.type==='slider'">
|
||||||
|
<slider style="width: 100%;" :activeColor="themeColor" :value="sItem.value"
|
||||||
|
:min="sItem.componentProps.min||0" :max="sItem.componentProps.max||100"
|
||||||
|
:step="sItem.componentProps.step||1"
|
||||||
|
:show-value="sItem.componentProps['show-value']||true"
|
||||||
|
@change="onSliderChange($event,sIndex,ssItem,index)" />
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="le-dropdown-footer">
|
||||||
|
<view class="le-dropdown-reset" @click="onFilterReset(item,index)">重置</view>
|
||||||
|
<view class="le-dropdown-confirm" @click="onFilterConfirm(item,index)">
|
||||||
|
{{item.confirmText||'确定'}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
|
<view class="le-dropdown-content-mask" @click="close"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
/**
|
||||||
|
* menuList 导航数据
|
||||||
|
* @property {String} title 导航名称
|
||||||
|
* @property {String} type =[cell|picker|sort|click|filter] 导航点击展示的类型
|
||||||
|
* @value cell 下拉选择(单选)
|
||||||
|
* @value picker 级联动
|
||||||
|
* @value sort 排序
|
||||||
|
* @value click 点击
|
||||||
|
* @value filter 复杂筛选
|
||||||
|
* @property {String} value 导航当前选中的值
|
||||||
|
* @property {Array} options 导航展示可选的数据值
|
||||||
|
* */
|
||||||
|
import {
|
||||||
|
ref,
|
||||||
|
computed,
|
||||||
|
getCurrentInstance,
|
||||||
|
onMounted
|
||||||
|
} from "vue";
|
||||||
|
import cloneDeep from './utils/cloneDeep.js';
|
||||||
|
import hexToRgb from './utils/hexToRgb.js';
|
||||||
|
import LeDropdownPicker from "./components/le-picker.vue";
|
||||||
|
const props = defineProps({
|
||||||
|
// 导航数据
|
||||||
|
menuList: {
|
||||||
|
type: Array,
|
||||||
|
default: () => {
|
||||||
|
return [
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 主题的颜色
|
||||||
|
themeColor: {
|
||||||
|
type: String,
|
||||||
|
default: "#3185FF"
|
||||||
|
},
|
||||||
|
// 没选中的颜色
|
||||||
|
inactiveColor: {
|
||||||
|
type: String,
|
||||||
|
default: "#333333"
|
||||||
|
},
|
||||||
|
// 过渡时间
|
||||||
|
duration: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 300
|
||||||
|
},
|
||||||
|
// 是否吸顶
|
||||||
|
isCeiling: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const emits = defineEmits(["open", "close", "update:menuList", "onConfirm", "onChange"])
|
||||||
|
// 初始化数据用于重置使用
|
||||||
|
const initMenuList = cloneDeep(props.menuList)
|
||||||
|
const instance = getCurrentInstance(); // 获取组件实例
|
||||||
|
// 下拉出来部分的样式
|
||||||
|
const popupStyle = computed(() => {
|
||||||
|
let style = {};
|
||||||
|
// 进行Y轴位移,展开状态时,恢复原位。收齐状态时,往上位移100%,进行隐藏
|
||||||
|
style.transform = `translateY(${active.value ? 0 : '-100%'})`
|
||||||
|
style['transition-duration'] = props.duration / 1000 + 's';
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
// 当前是第几个菜单处于激活状态
|
||||||
|
const current = ref(99999);
|
||||||
|
// 外层内容的样式,初始时处于底层,且透明
|
||||||
|
const contentStyle = ref({
|
||||||
|
zIndex: -1,
|
||||||
|
opacity: 0
|
||||||
|
})
|
||||||
|
const active = ref(false) // 下拉菜单的状态
|
||||||
|
const contentHeight = ref(0)
|
||||||
|
const leDropdownContentPopupRef = ref(null)
|
||||||
|
const windowTop = ref(0)
|
||||||
|
uni.getSystemInfo({
|
||||||
|
success(e) {
|
||||||
|
windowTop.value = e.windowTop;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 点击菜单
|
||||||
|
const menuClick = (index) => {
|
||||||
|
getContentHeight()
|
||||||
|
switch (props.menuList[index].type) {
|
||||||
|
case 'sort':
|
||||||
|
onSort(index);
|
||||||
|
break;
|
||||||
|
case 'click':
|
||||||
|
onClick(index);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// 如果点击时的索引和当前激活项索引相同,意味着点击了激活项,需要收起下拉菜单
|
||||||
|
if (index === current.value) {
|
||||||
|
close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
open(index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 打开当前筛选窗
|
||||||
|
const open = (index) => {
|
||||||
|
// 展开时,设置下拉内容的样式
|
||||||
|
active.value = true;
|
||||||
|
contentStyle.value.zIndex = 11;
|
||||||
|
contentStyle.value.opacity = 1;
|
||||||
|
contentStyle.value.bottom = `0px`;
|
||||||
|
contentStyle.value.top = `80rpx`;
|
||||||
|
// 标记展开状态以及当前展开项的索引
|
||||||
|
current.value = index;
|
||||||
|
emits("open", current.value)
|
||||||
|
}
|
||||||
|
// 关闭当前筛选窗
|
||||||
|
const close = () => {
|
||||||
|
active.value = false;
|
||||||
|
contentStyle.value.opacity = 0;
|
||||||
|
// 等动画结束后,再移除下拉菜单中的内容,否则直接移除,也就没有下拉菜单收起的效果了
|
||||||
|
setTimeout(() => {
|
||||||
|
contentStyle.value.zIndex = -1;
|
||||||
|
current.value = 99999;
|
||||||
|
contentStyle.value.bottom = `calc(100vh - ${contentHeight.value + windowTop.value}px)`
|
||||||
|
contentStyle.value.top = 'auto';
|
||||||
|
}, props.duration)
|
||||||
|
emits("close", current.value)
|
||||||
|
}
|
||||||
|
// 获取下拉菜单内容的高度
|
||||||
|
const getContentHeight = () => {
|
||||||
|
uni.createSelectorQuery()
|
||||||
|
.in(instance)
|
||||||
|
.selectAll('.le-dropdown-menu')
|
||||||
|
.boundingClientRect()
|
||||||
|
.exec(data => {
|
||||||
|
contentHeight.value = data[0][0].bottom
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 点击排序
|
||||||
|
const onSort = (index) => {
|
||||||
|
const type = current.value === 99999 ? current.value : props.menuList[current.value].type
|
||||||
|
switch (type) {
|
||||||
|
case 'sort':
|
||||||
|
case 'click':
|
||||||
|
case 99999:
|
||||||
|
start()
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
close();
|
||||||
|
setTimeout(() => {
|
||||||
|
start()
|
||||||
|
}, props.duration)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
function start() {
|
||||||
|
const menuList = cloneDeep(props.menuList);
|
||||||
|
current.value = index;
|
||||||
|
menuList[index].value = !menuList[index].value ? 'asc' : menuList[index].value == 'asc' ? 'desc' :
|
||||||
|
null;
|
||||||
|
emits("update:menuList", menuList)
|
||||||
|
emits("onConfirm", menuList[index])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 点击按钮
|
||||||
|
const onClick = (index) => {
|
||||||
|
const type = current.value === 99999 ? current.value : props.menuList[current.value].type
|
||||||
|
switch (type) {
|
||||||
|
case 'sort':
|
||||||
|
case 'click':
|
||||||
|
case 99999:
|
||||||
|
start()
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
close();
|
||||||
|
setTimeout(() => {
|
||||||
|
start()
|
||||||
|
}, props.duration)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
function start() {
|
||||||
|
const menuList = cloneDeep(props.menuList);
|
||||||
|
current.value = index;
|
||||||
|
emits("onConfirm", menuList[index])
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// 单选列表选中事件
|
||||||
|
const onSelectCell = (sItem, index) => {
|
||||||
|
const menuList = cloneDeep(props.menuList);
|
||||||
|
menuList[index].title = sItem.label;
|
||||||
|
menuList[index].value = sItem.value;
|
||||||
|
emits("update:menuList", menuList)
|
||||||
|
close();
|
||||||
|
emits("onConfirm", menuList[index])
|
||||||
|
}
|
||||||
|
// 筛选单选选中事件
|
||||||
|
const onRadioFilter = (sIndex, ssItem, index) => {
|
||||||
|
const menuList = cloneDeep(props.menuList);
|
||||||
|
menuList[index].children[sIndex].value = ssItem.value;
|
||||||
|
emits("update:menuList", menuList)
|
||||||
|
emits("onChange", menuList[index], sIndex)
|
||||||
|
}
|
||||||
|
// 筛选多选选中事件
|
||||||
|
const onCheckboxFilter = (sIndex, ssItem, index) => {
|
||||||
|
const menuList = cloneDeep(props.menuList);
|
||||||
|
const indexs = menuList[index].children[sIndex].value.indexOf(ssItem.value)
|
||||||
|
if (indexs != -1) {
|
||||||
|
menuList[index].children[sIndex].value.splice(indexs, 1)
|
||||||
|
} else {
|
||||||
|
menuList[index].children[sIndex].value.push(ssItem.value)
|
||||||
|
}
|
||||||
|
emits("update:menuList", menuList)
|
||||||
|
emits("onChange", menuList[index], sIndex)
|
||||||
|
}
|
||||||
|
// 滑块值的变化事件
|
||||||
|
const onSliderChange = (event, sIndex, ssItem, index) => {
|
||||||
|
const menuList = cloneDeep(props.menuList);
|
||||||
|
menuList[index].children[sIndex].value = event.detail.value;
|
||||||
|
emits("update:menuList", menuList)
|
||||||
|
emits("onChange", menuList[index], sIndex)
|
||||||
|
}
|
||||||
|
// 筛选选中事件
|
||||||
|
const onSelectFilter = (sIndex, ssItem, index) => {
|
||||||
|
const menuList = cloneDeep(props.menuList);
|
||||||
|
menuList[index].active[sIndex] = ssItem.value;
|
||||||
|
emits("update:menuList", menuList)
|
||||||
|
emits("onChange", menuList[index], sIndex)
|
||||||
|
}
|
||||||
|
// 重置筛选
|
||||||
|
const onFilterReset = (item, index) => {
|
||||||
|
const menuList = cloneDeep(props.menuList);
|
||||||
|
menuList[index].children.forEach((items, indexs) => {
|
||||||
|
items.value = initMenuList[index].children[indexs].value
|
||||||
|
})
|
||||||
|
emits("update:menuList", menuList)
|
||||||
|
// close();
|
||||||
|
// emits("onConfirm",menuList[index])
|
||||||
|
}
|
||||||
|
// 确定筛选
|
||||||
|
const onFilterConfirm = (item, index) => {
|
||||||
|
close();
|
||||||
|
const menuList = cloneDeep(props.menuList);
|
||||||
|
emits("onConfirm", menuList[index])
|
||||||
|
}
|
||||||
|
const bindFun = (data) => {
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
onMounted(() => {
|
||||||
|
getContentHeight()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.le-flex {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.le-dropdown {
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.le-dropdown-menu {
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
z-index: 11;
|
||||||
|
height: 80rpx;
|
||||||
|
|
||||||
|
.le-dropdown-menu-item {
|
||||||
|
height: 100%;
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.le-dropdown-menu-item-text {
|
||||||
|
font-size: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.le-dropdown-menu-item-arrow {
|
||||||
|
margin-left: 6rpx;
|
||||||
|
transition: transform .3s;
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
width: 10rpx;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: calc(50% - 8rpx);
|
||||||
|
right: -2rpx;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
border: 6rpx solid transparent;
|
||||||
|
border-bottom-color: #C1C1C1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: calc(50% + 8rpx);
|
||||||
|
right: -2rpx;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
border: 6rpx solid transparent;
|
||||||
|
border-top-color: #C1C1C1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.le-dropdown-menu-item-arrow_top {
|
||||||
|
&::before {
|
||||||
|
border-bottom-color: var(--dropdownThemeColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.le-dropdown-menu-item-arrow_bottom {
|
||||||
|
&::after {
|
||||||
|
border-top-color: var(--dropdownThemeColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.le-dropdown-menu-item-basicarrow {
|
||||||
|
margin-left: 6rpx;
|
||||||
|
transition: transform .3s;
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
border: 6rpx solid transparent;
|
||||||
|
border-bottom: 0rpx solid transparent;
|
||||||
|
border-top-color: #C1C1C1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.le-dropdown-menu-item-basicarrow_rotate {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
border-top-color: var(--dropdownThemeColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.le-dropdown-content {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 8;
|
||||||
|
width: 100%;
|
||||||
|
left: 0px;
|
||||||
|
bottom: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
|
||||||
|
.le-dropdown-content-mask {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 9;
|
||||||
|
background: rgba(0, 0, 0, .3);
|
||||||
|
width: 100%;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.le-dropdown-content-popup {
|
||||||
|
position: relative;
|
||||||
|
max-height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
overscroll-behavior: contain;
|
||||||
|
z-index: 10;
|
||||||
|
transition: all 0.3s;
|
||||||
|
transform: translate3D(0, -100%, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.le-dropdown-ceiling{
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.le-dropdown-popup-content {
|
||||||
|
font-size: 28rpx;
|
||||||
|
border-radius: 0 0 20rpx 20rpx;
|
||||||
|
background-color: #ffffff;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 单选列表
|
||||||
|
.le-dropdown-cell {
|
||||||
|
padding: 0 30rpx;
|
||||||
|
|
||||||
|
.le-dropdown-cell-item {
|
||||||
|
padding: 20rpx 0;
|
||||||
|
color: #333333;
|
||||||
|
font-size: 28rpx;
|
||||||
|
border-bottom: 1rpx solid #D5D5D5;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
.le-dropdown-cell-active-text{
|
||||||
|
flex: 1;
|
||||||
|
padding-right: 20rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.le-dropdown-cell-item:last-child {
|
||||||
|
border-bottom: 0rpx solid #D5D5D5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.le-dropdown-cell-active {
|
||||||
|
color: var(--dropdownThemeColor);
|
||||||
|
.le-dropdown-cell-active-icon {
|
||||||
|
width: 12rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
border-color: var(--dropdownThemeColor);
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0 4rpx 4rpx 0;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 筛选
|
||||||
|
.le-dropdown-filter {
|
||||||
|
|
||||||
|
.le-dropdown-filter-item {
|
||||||
|
padding: 0 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.le-dropdown-filter-title {
|
||||||
|
padding-top: 34rpx;
|
||||||
|
margin-bottom: 18rpx;
|
||||||
|
color: #333333;
|
||||||
|
font-size: 24rpx;
|
||||||
|
|
||||||
|
.le-dropdown-filter-subtitle {
|
||||||
|
margin-left: 10rpx;
|
||||||
|
color: var(--dropdownThemeColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.le-dropdown-filter-content {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.le-dropdown-filter-box {
|
||||||
|
width: 200rpx;
|
||||||
|
margin-right: 30rpx;
|
||||||
|
margin-bottom: 14rpx;
|
||||||
|
padding: 18rpx 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333333;
|
||||||
|
background-color: #F5F5F5;
|
||||||
|
border-radius: 999rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.le-dropdown-filter-box-active {
|
||||||
|
color: var(--dropdownThemeColor);
|
||||||
|
background-color: rgba(var(--dropdownThemeColorRgb), 0.04);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.le-dropdown-footer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 14rpx;
|
||||||
|
|
||||||
|
.le-dropdown-reset {
|
||||||
|
flex: 1;
|
||||||
|
margin: 26rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 68rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
color: var(--dropdownThemeColor);
|
||||||
|
border: 2rpx solid var(--dropdownThemeColor);
|
||||||
|
border-radius: 999rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.le-dropdown-confirm {
|
||||||
|
flex: 1;
|
||||||
|
margin: 26rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 68rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
background-color: var(--dropdownThemeColor);
|
||||||
|
border: 2rpx solid var(--dropdownThemeColor);
|
||||||
|
color: #ffffff;
|
||||||
|
border-radius: 999rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
function deepClone(obj) {
|
||||||
|
let result = typeof obj.splice === "function" ? [] : {};
|
||||||
|
if (obj && typeof obj === 'object') {
|
||||||
|
for (let key in obj) {
|
||||||
|
if (obj[key] && typeof obj[key] === 'object') {
|
||||||
|
result[key] = deepClone(obj[key]);//如果对象的属性值为object的时候,递归调用deepClone,即在吧某个值对象复制一份到新的对象的对应值中。
|
||||||
|
} else {
|
||||||
|
result[key] = obj[key];//如果对象的属性值不为object的时候,直接复制参数对象的每一个键值到新的对象对应的键值对中。
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default deepClone
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
export default function(hexStr){
|
||||||
|
//十六进制颜色值的正则表达式
|
||||||
|
let reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
|
||||||
|
let sColor = hexStr.toLowerCase();
|
||||||
|
if (sColor && reg.test(sColor)) {
|
||||||
|
if (sColor.length === 4) {
|
||||||
|
let sColorNew = "#";
|
||||||
|
for (let i = 1; i < 4; i += 1) {
|
||||||
|
sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1));
|
||||||
|
}
|
||||||
|
sColor = sColorNew;
|
||||||
|
}
|
||||||
|
//处理六位的颜色值f
|
||||||
|
let sColorChange = [];
|
||||||
|
for (let i = 1; i < 7; i += 2) {
|
||||||
|
sColorChange.push(parseInt(`0x${sColor.slice(i, i + 2)}`));
|
||||||
|
}
|
||||||
|
let rgbText = sColorChange.join(",")
|
||||||
|
return rgbText;
|
||||||
|
} else {
|
||||||
|
return sColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
81
uni_modules/le-dropdown/package.json
Normal file
81
uni_modules/le-dropdown/package.json
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
{
|
||||||
|
"id": "le-dropdown",
|
||||||
|
"displayName": "le-dropdown(多功能下拉筛选菜单+主题色)",
|
||||||
|
"version": "1.0.4",
|
||||||
|
"description": "下拉筛选、多级级联、排序、点击菜单组件;兼容小程序、H5、app;可以更换主题色。",
|
||||||
|
"keywords": [
|
||||||
|
"le-dropdown",
|
||||||
|
"dropdown",
|
||||||
|
"筛选",
|
||||||
|
"菜单",
|
||||||
|
"下拉"
|
||||||
|
],
|
||||||
|
"repository": "https://gitee.com/le-ui/le-dropdown",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": "^3.6.18"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "插件不采集任何数据",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": "",
|
||||||
|
"type": "component-vue"
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "n",
|
||||||
|
"vue3": "y"
|
||||||
|
},
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "u"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "n",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "y",
|
||||||
|
"百度": "u",
|
||||||
|
"字节跳动": "y",
|
||||||
|
"QQ": "y"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "n",
|
||||||
|
"联盟": "n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
72
uni_modules/le-dropdown/readme.md
Normal file
72
uni_modules/le-dropdown/readme.md
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
# le-dropdown
|
||||||
|
|
||||||
|
### 使用方式
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
<le-dropdown
|
||||||
|
v-model:menuList="menuList"
|
||||||
|
themeColor="#3185FF"
|
||||||
|
:duration="300"
|
||||||
|
:isCeiling="false"
|
||||||
|
@onConfirm="onConfirm"
|
||||||
|
@onChange="onChange"
|
||||||
|
></le-dropdown>
|
||||||
|
```
|
||||||
|
### 组件的属性说明如下:
|
||||||
|
|
||||||
|
| 属性 | 类型 | 默认值 | 必填 | 说明 |
|
||||||
|
| ---------------- | ------- | ------- | ---- | ------------------------------ |
|
||||||
|
| v-model:menuList | Array | [] | 是 | 设置整个菜单筛选的配置数居 |
|
||||||
|
| themeColor | String | #3185FF | 否 | 整个组件的主题颜色 |
|
||||||
|
| duration | Number | 300 | 否 | 动画的执行时间 |
|
||||||
|
| isCeiling | Boolean | false | 否 | 是否自动吸顶(采用sticky规则) |
|
||||||
|
|
||||||
|
#### menuList参数说明:
|
||||||
|
|
||||||
|
| 属性 | 类型 | 必填 | 说明 |
|
||||||
|
| -------------- | --------------------- | ---- | ---------------------------------------------------------- |
|
||||||
|
| title | String | 是 | 菜单名称 |
|
||||||
|
| type | String | 是 | 菜单筛选展示的类型:cell\|picker\|sort\|click\|filter |
|
||||||
|
| value | Number\|String\|Array | 是 | 菜单对应的值 |
|
||||||
|
| options | Array | 否 | 菜单配置的组件参数数据,**见下**: |
|
||||||
|
| children | Array | 否 | 菜单配置的组件参数数据(当前只用在filter类型),**见下**: |
|
||||||
|
| componentProps | Object | 否 | 菜单对应type的组件参数(当前只用在picker类型),**见下**: |
|
||||||
|
|
||||||
|
##### options参数说明:
|
||||||
|
|
||||||
|
| 属性 | 类型 | 必填 | 说明 |
|
||||||
|
| -------- | -------------- | ---- | ------------------------------- |
|
||||||
|
| label | String | 是 | 属性名,显示在页面上 |
|
||||||
|
| value | Number\|String | 是 | 属性值,保存在父级的value属性上 |
|
||||||
|
| children | options[] | 否 | 子层级(当前只在picker上使用) |
|
||||||
|
|
||||||
|
##### **children参数(filter)说明:**
|
||||||
|
|
||||||
|
| 属性 | 类型 | 必填 | 说明 |
|
||||||
|
| ------- | -------------- | ---- | ------------------------------------------- |
|
||||||
|
| title | String | 是 | 菜单名称 |
|
||||||
|
| type | String | 是 | 菜单筛选展示的类型:radio\|slider\|checkbox |
|
||||||
|
| value | Number\|String | 是 | 菜单对应的值 |
|
||||||
|
| options | Array | 是 | 菜单配置的组件参数数据,**见上**: |
|
||||||
|
|
||||||
|
###### children下type参数说明:
|
||||||
|
|
||||||
|
- radio:单选
|
||||||
|
- checkbox:多选
|
||||||
|
- slider:进度(存在componentProps与type同级参数,对象里的值为uniapp原生的slider里的参数)
|
||||||
|
|
||||||
|
##### componentProps参数(picker)说明:
|
||||||
|
|
||||||
|
| 属性 | 类型 | 默认值 | 必填 | 说明 |
|
||||||
|
| ---------- | ------ | ------------------------------------------------------ | ---- | --------------------------------------- |
|
||||||
|
| colNum | Number | 1 | 否 | 级联的列数 |
|
||||||
|
| options | Array | - | 是 | 菜单配置的组件参数数据,**见上**: |
|
||||||
|
| fieldNames | Object | { label: `label`, value: `value`, options: `options` } | 否 | 自定义节点 label、value、options 的字段 |
|
||||||
|
|
||||||
|
### 事件
|
||||||
|
|
||||||
|
| 事件名称 | 回调参数 | 说明 |
|
||||||
|
| --------- | -------------------- | ------------------------------------------------------------ |
|
||||||
|
| onConfirm | (data) => void | 确定事件回调,data为当前确认选中的菜单数据 |
|
||||||
|
| onChange | (data,index) => void | 改变事件,data为当前操作菜单数据,index为当前操作菜单第index个索引发生变化 |
|
||||||
|
|
||||||
Reference in New Issue
Block a user