@@ -0,0 +1,35 @@ | |||
<template> | |||
<view class="radioPopup"> | |||
<u-popup :show="show" @close="close" @open="open"> | |||
<view> | |||
<text>出淤泥而不染,濯清涟而不妖</text> | |||
</view> | |||
</u-popup> | |||
</view> | |||
</template> | |||
<script> | |||
export default { | |||
name: 'radioPopup', | |||
data() { | |||
return { | |||
show: false | |||
} | |||
}, | |||
props: { | |||
}, | |||
methods: { | |||
open() { | |||
// console.log('open'); | |||
}, | |||
close() { | |||
this.show = false | |||
// console.log('close'); | |||
} | |||
} | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
</style> |
@@ -42,7 +42,9 @@ | |||
<view class="content" @click.stop="isSelect"> | |||
<u-row justify="space-between" gutter="10"> | |||
<u-col span="7"> | |||
<view class="demo-layout"> | |||
<view class="demo-layout" @click="toOpen"> | |||
<view class="left-layout"> | |||
<text>11111111111</text> | |||
</view> | |||
@@ -51,6 +53,9 @@ | |||
src="@/static/image/earlyWarning/arrowRight.png" mode=""></image> | |||
</view> | |||
</view> | |||
<jp-select-plus ref="selectPlus" :isShow="false" color="#2388FF" placeholder="请选择" | |||
isSearch v-model="va3" :list="listc"></jp-select-plus> | |||
</u-col> | |||
<u-col span="5"> | |||
<view class="demo-layout"> | |||
@@ -94,22 +99,112 @@ | |||
</view> | |||
<view class="tableBox"> | |||
<u-empty marginTop="100rpx" :show="false" mode="list" text="暂无数据"></u-empty> | |||
<u-empty marginTop="100rpx" :show="false" mode="warnList" text="暂无数据"></u-empty> | |||
<u-list @scrolltolower="scrolltolower" style="height: calc(100% - 0rpx);"> | |||
<u-list-item v-for="(item, index) in list" :key="index"> | |||
<u-list-item v-for="(item, index) in warnList" :key="index"> | |||
<view class="liBox"> | |||
<view class="topCard"> | |||
<view class="pic"> | |||
<image src="@/static/image/earlyWarning/warnBack.png" mode=""></image> | |||
</view> | |||
<view class="rightCard"> | |||
<view class="firstCard"> | |||
<view class="schoolName"> | |||
学校名称学校名称学校名称学校名称 | |||
</view> | |||
<view class="statusBox" :class="[item.warnHand == 1?'handle':'nohandle']"> | |||
{{item.warnHand == 1 ? '已处理' : '未处理'}} | |||
</view> | |||
</view> | |||
<view class="secondCard"> | |||
<image style="width: 30rpx;height: 30rpx;" | |||
src="@/static/image/earlyWarning/warnType.png" mode=""></image> | |||
<view class="txt"> | |||
警告类型:周界入侵 | |||
</view> | |||
</view> | |||
<view class="thirdCard"> | |||
<image style="width: 30rpx;height: 30rpx;" | |||
src="@/static/image/earlyWarning/warnVideo.png" mode=""></image> | |||
<view class="txt"> | |||
警告摄像头:厨房(良景) | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
<view class="midCard"> | |||
<u-row> | |||
<u-col span="6"> | |||
<view class="midContent"> | |||
姓名:杨云 | |||
</view> | |||
</u-col> | |||
<u-col span="6"> | |||
<view class="midContent"> | |||
系部:安环部 | |||
</view> | |||
</u-col> | |||
</u-row> | |||
<u-row> | |||
<u-col span="6"> | |||
<view class="midContent"> | |||
专业:环艺 | |||
</view> | |||
</u-col> | |||
<u-col span="6"> | |||
<view class="midContent"> | |||
班级:第二班 | |||
</view> | |||
</u-col> | |||
</u-row> | |||
<u-row> | |||
<u-col span="12"> | |||
<view class="midContent"> | |||
时间:2024-08-15 11:59:12 | |||
</view> | |||
</u-col> | |||
</u-row> | |||
</view> | |||
<view class="btoCard"> | |||
<view class="leftBox btoBox"> | |||
<image src="@/static/image/earlyWarning/detail.png" mode=""></image> | |||
<view class="txt"> | |||
查看 | |||
</view> | |||
</view> | |||
<view class="midBox btoBox"> | |||
<image v-if="item.warnHand == 1" src="@/static/image/earlyWarning/handle.png" | |||
mode=""></image> | |||
<image v-if="item.warnHand == 0" | |||
src="@/static/image/earlyWarning/handleDisabled.png" mode=""></image> | |||
<view :class="[item.warnHand == 1?'txt':'disabled']"> | |||
处理 | |||
</view> | |||
</view> | |||
<view class="rightBox btoBox"> | |||
<image src="@/static/image/earlyWarning/delete.png" mode=""></image> | |||
<view class="txt"> | |||
删除 | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
</u-list-item> | |||
<u-loadmore :status="status" /> | |||
</u-list> | |||
</view> | |||
</view> | |||
<radioPopup></radioPopup> | |||
</view> | |||
</template> | |||
<script> | |||
import radioPopup from './components/radioPopup.vue' | |||
export default { | |||
components: { | |||
radioPopup | |||
}, | |||
data() { | |||
return { | |||
showSelectModel: false, | |||
@@ -130,17 +225,89 @@ | |||
} | |||
], | |||
isShowSearch: false, | |||
list: [{}, {}, {}, {}, {}, {}, {}, {}, {}, ], | |||
warnList: [{ | |||
warnHand: 0 | |||
}, {}, {}, {}, {}, {}, {}, {}, {}, ], | |||
isLoading: false, | |||
status: 'loadmore', //loading正在加载 loadmore加载更多 nomore没有更多了 | |||
listc: [{ | |||
code: 1, | |||
name: 'dasda' | |||
},{ | |||
code: 2, | |||
name: 'dasda' | |||
}, | |||
{ | |||
code: 3, | |||
name: 'dasda' | |||
}, | |||
{ | |||
code: 4, | |||
name: 'dasda' | |||
}, | |||
{ | |||
code: 5, | |||
name: 'dasda' | |||
}, | |||
{ | |||
code: 6, | |||
name: 'dasda' | |||
}, | |||
{ | |||
code: 7, | |||
name: 'dasda' | |||
}, | |||
{ | |||
code: 8, | |||
name: 'dasda' | |||
}, | |||
{ | |||
code: 9, | |||
name: 'dasda' | |||
}, | |||
{ | |||
code: 10, | |||
name: 'dasda' | |||
}, | |||
{ | |||
code: 11, | |||
name: 'dasda' | |||
}, | |||
{ | |||
code: 12, | |||
name: 'dasda' | |||
}, | |||
{ | |||
code: 13, | |||
name: '你好' | |||
}] | |||
} | |||
}, | |||
filters: { | |||
statusChange(val) { | |||
switch (val) { | |||
case 'todo': | |||
return '我的待办' | |||
break; | |||
case 'send': | |||
return '由我发起' | |||
break; | |||
case 'done': | |||
return '我的已办' | |||
break; | |||
default: | |||
} | |||
}, | |||
}, | |||
onLoad() { | |||
// 隐藏导航栏 | |||
this.loadmore() | |||
}, | |||
methods: { | |||
toOpen(){ | |||
this.$refs.selectPlus.open() | |||
}, | |||
open() { | |||
// console.log('open'); | |||
}, | |||
@@ -181,10 +348,10 @@ | |||
this.status = 'loading' | |||
setTimeout(() => { | |||
for (let i = 0; i < 1; i++) { | |||
this.list.push({}, {}) | |||
this.warnList.push({}, {}) | |||
} | |||
// 获取到的总条数>=接口总条数 | |||
if (this.list.length >= 14) { | |||
if (this.warnList.length >= 14) { | |||
this.status = 'nomore' | |||
} else { | |||
this.status = 'loadmore' | |||
@@ -290,12 +457,11 @@ | |||
} | |||
.searchDialog { | |||
// height: calc(100% - 360rpx); | |||
position: absolute; | |||
z-index: 999; | |||
z-index: 990; | |||
top: 89rpx; | |||
width: 100%; | |||
height: calc(100vh - 600rpx); | |||
height: calc(100vh - 375rpx - 100rpx); | |||
font-size: 26rpx; | |||
background: rgba(0, 0, 0, 0.2); | |||
@@ -377,10 +543,131 @@ | |||
.liBox { | |||
background: #fff; | |||
padding: 10px; | |||
padding: 20px 15px; | |||
box-sizing: border-box; | |||
border-radius: 20px; | |||
margin-bottom: 10px; | |||
.topCard { | |||
display: flex; | |||
.pic { | |||
image { | |||
width: 160rpx; | |||
height: 160rpx; | |||
border-radius: 4px; | |||
} | |||
} | |||
.rightCard { | |||
margin-left: 20rpx; | |||
.firstCard { | |||
display: flex; | |||
justify-content: space-between; | |||
align-items: center; | |||
margin-bottom: 20rpx; | |||
.schoolName { | |||
font-size: 32rpx; | |||
color: #333333; | |||
overflow: hidden; | |||
word-wrap: break-word; | |||
white-space: pre-wrap; | |||
// font-size: 14px; | |||
display: -webkit-box; | |||
-webkit-box-orient: vertical; | |||
-webkit-line-clamp: 1; | |||
} | |||
.statusBox { | |||
width: 140rpx; | |||
flex-shrink: 1; | |||
text-align: center; | |||
height: 50rpx; | |||
line-height: 50rpx; | |||
font-size: 28rpx; | |||
border-radius: 8rpx; | |||
color: #fff; | |||
} | |||
.handle { | |||
background: rgba(15, 175, 118, 0.1); | |||
color: #0FAF76; | |||
} | |||
.nohandle { | |||
background: rgba(239, 45, 45, 0.1); | |||
color: rgba(239, 45, 45, 1); | |||
} | |||
} | |||
.secondCard, | |||
.thirdCard { | |||
display: flex; | |||
align-items: center; | |||
margin-top: 18rpx; | |||
.txt { | |||
font-size: 28rpx; | |||
margin-left: 10rpx; | |||
color: #333333; | |||
} | |||
} | |||
} | |||
} | |||
.midCard { | |||
font-size: 28rpx; | |||
.midContent { | |||
margin-top: 18rpx; | |||
} | |||
} | |||
.btoCard { | |||
border-top: 1px solid rgba(0, 0, 0, 0.1); | |||
margin-top: 30rpx; | |||
padding: 18px 0 0 0; | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
.btoBox { | |||
width: 33.3%; | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
position: relative; | |||
image { | |||
width: 40rpx; | |||
height: 40rpx; | |||
margin-right: 15rpx; | |||
} | |||
} | |||
.btoBox:not(:last-child)::before { | |||
content: ''; | |||
display: block; | |||
width: 1px; | |||
height: 100%; | |||
background: rgba(0, 0, 0, 0.1); | |||
position: absolute; | |||
right: 0px; | |||
} | |||
.midBox { | |||
.txt { | |||
color: #333333; | |||
} | |||
.disabled { | |||
color: #777777; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
@@ -0,0 +1,4 @@ | |||
## 1.1(2023-08-17) | |||
修复多选显示问题 | |||
## 1.0.1(2023-08-17) | |||
1.0 |
@@ -0,0 +1,682 @@ | |||
<template> | |||
<view class="showData" ref="echartsWrapper" :class="[isLine?'isLine':'']"> | |||
<view v-if="isShow" :class="isLineFeed?'showData-field-line':'showData-field-input'" @click="open"> | |||
<view class="showData-field-label" | |||
:style="{minWidth:isLineFeed?'':labelWidths,width:isLineFeed?'':labelWidths,color:labelColor}" | |||
v-if="label"><span v-if="required" style="color: red">*</span>{{label}}</view> | |||
<!-- 多选 --> | |||
<view :class="direction=='left'?'textleft':'textR'" :style="{width: inpeWidth}" | |||
class="inputs checkbox showDatas" v-if="checkbox && !clickable"> | |||
<view :style="{color: value?valueColor?valueColor:'':'#999',width: inpeWidthLfet}" | |||
:class="isoverflow?'showData-field-pu':''"> | |||
<view v-if="ListXz.length>0"> | |||
<view v-if="!isJoin"> | |||
<view v-for="(item,index) in ListXz" :key="'a'+index">{{KeyType?item[showName]:item}}</view> | |||
</view> | |||
<view v-else> | |||
{{KeyType?ListXz.map(el=>{return el[showName]}).join(','):ListXz.map(el=>{return el}).join(',')}} | |||
</view> | |||
</view> | |||
<view :style="{color: placeholderColor }" v-else>{{placeholder}}</view> | |||
</view> | |||
<view v-if="arrow" class="arrows"> | |||
<image src="./arrow.png" style="width: 30rpx;height: 30rpx;"></image> | |||
</view> | |||
</view> | |||
<!-- 单选 --> | |||
<view :style="{width: inpeWidth}" :class="direction=='left'?'textleft':'textR'" class="inputs showDatas" | |||
v-if="!checkbox && !clickable"> | |||
<view :style="{color: ListXz.length>0?valueColor?valueColor:'':placeholderColor,width: inpeWidthLfet}" | |||
:class="isoverflow?'showData-field-pu':''"> | |||
{{ListXz.length>0?(KeyType?ListXz[0][showName]:ListXz[0]):placeholder}} | |||
</view> | |||
<view v-if="arrow" class="arrows"> | |||
<image src="./arrow.png" style="width: 30rpx;height: 30rpx;"></image> | |||
</view> | |||
</view> | |||
<!-- 可以点击 --> | |||
<view :style="{width: inpeWidth}" :class="direction=='left'?'textleft':'textR'" class="inputs showDatas" | |||
v-if="clickable"> | |||
<view :style="{color: value?valueColor?valueColor:'':placeholderColor,width: inpeWidthLfet}" | |||
:class="isoverflow?'showData-field-pu':''">{{value?value:placeholder}}</view> | |||
<view v-if="arrow" class="arrows"> | |||
<image src="./arrow.png" style="width: 30rpx;height: 30rpx;"></image> | |||
</view> | |||
</view> | |||
</view> | |||
<slot /> | |||
<view class="bottomPopup" v-if="showPicker"> | |||
<transition name="slide-up" appear> | |||
<view class="popup-content"> | |||
<view class="pop-header" v-if="isHeader"> | |||
<span class="pop-header-left" @click="onCancel">{{cancelText}}</span> | |||
<span class="pop-header-title">{{title}}</span> | |||
<span class="pop-header-right" :style="{color}" @click="onConfirm">{{confirmText}}</span> | |||
</view> | |||
<view class="pop-header" v-if="!isHeader"> | |||
<slot name="popHeader" /> | |||
</view> | |||
<view v-if="isSearch"> | |||
<view style="background-color: #fff;padding: 15rpx 25rpx;"> | |||
<view | |||
style="border-radius: 10rpx;padding: 0 25rpx;;display: flex;justify-content: center;background-color: #f5f5f5;line-height: 65rpx;height: 65rpx;"> | |||
<view style="display: flex;justify-content: center;flex: 1;"> | |||
<input style="line-height: 65rpx;height: 65rpx;flex: 1;" v-model.trim="key" | |||
:placeholder="headerPlaceholder" /> | |||
</view> | |||
<view @click="onSearch" :style="{color}" | |||
style="width: 80rpx;text-align: center;margin-left: 25rpx;"> | |||
搜索 | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
<view v-if="isLoading && popList.length==0" class="pop-main loading"> | |||
<loading></loading> | |||
</view> | |||
<view v-else> | |||
<view class="pop-main"> | |||
<view v-if="popList.length>0"> | |||
<checkbox-group v-if="checkbox" @change="checkboxChange"> | |||
<label class="uni-list-cell uni-list-cell-pd" v-for="(item, index) in popList" | |||
:key="KeyType?item[keys]:item"> | |||
<view>{{KeyType?item[showName]:item}}</view> | |||
<view> | |||
<checkbox :color="color" :value="KeyType?item[keys]:item" | |||
:checked="getChecked(KeyType?item[keys]:item)" /> | |||
</view> | |||
</label> | |||
</checkbox-group> | |||
<radio-group v-else @change="radioChange"> | |||
<label class="uni-list-cell uni-list-cell-pd" v-for="(item, index) in popList" | |||
:key="KeyType?item[keys]:item"> | |||
<view>{{KeyType?item[showName]:item}}</view> | |||
<view> | |||
<radio :color="color" :value="KeyType?item[keys]:item" | |||
:checked="(KeyType?item[keys]:item) == resultRadio" /> | |||
</view> | |||
</label> | |||
</radio-group> | |||
</view> | |||
<view v-else class="noData"> | |||
暂无可选数据 | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
</transition> | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
import loading from './loading.vue' | |||
export default { | |||
name: 'showData', | |||
components: { | |||
loading | |||
}, | |||
props: { | |||
list: { | |||
type: Array, | |||
default () { | |||
return [] | |||
}, | |||
}, | |||
value: { | |||
type: [String, Array, Number], | |||
default: '', | |||
}, | |||
valName: { | |||
type: String, | |||
default: '', | |||
}, | |||
keys: { | |||
//需要识别的code标识 | |||
type: String, | |||
default: 'code', | |||
}, | |||
showName: { | |||
//需要展示标识 | |||
type: String, | |||
default: 'name', | |||
}, | |||
direction: { | |||
type: String, | |||
default: 'left', | |||
}, | |||
clickable: { | |||
type: [Boolean, String], | |||
default: false, | |||
}, | |||
isShow: { | |||
type: [Boolean, String], | |||
default: true, | |||
}, | |||
isJoin: { | |||
type: [Boolean, String], | |||
default: false, | |||
}, | |||
label: { | |||
type: String, | |||
default: '', | |||
}, | |||
color: { | |||
type: String, | |||
default: '#00aaff', | |||
}, | |||
labelColor: { | |||
type: String, | |||
default: '#646566', | |||
}, | |||
placeholder: { | |||
type: String, | |||
default: '请选择', | |||
}, | |||
placeholderColor: { | |||
type: String, | |||
default: '#999', | |||
}, | |||
labelWidth: { | |||
type: String, | |||
default: '90px', | |||
}, | |||
valueColor: { | |||
type: String, | |||
default: '', | |||
}, | |||
required: { | |||
type: [Boolean, String], | |||
default: false, | |||
}, | |||
isLineFeed: { | |||
type: [Boolean, String], | |||
default: true, | |||
}, | |||
isLine: { | |||
//是否换显示线 | |||
type: [Boolean, String], | |||
default: true, | |||
}, | |||
isoverflow: { | |||
//是否超出隐藏 | |||
type: [Boolean, String], | |||
default: true, | |||
}, | |||
checkbox: { | |||
//是多选 | |||
type: [Boolean, String], | |||
default: false, | |||
}, | |||
disabled: { | |||
type: [Boolean, String], | |||
default: false, | |||
}, | |||
arrow: { | |||
type: [Boolean, String], | |||
default: true, | |||
}, | |||
title: { | |||
type: String, | |||
default: '请选择', | |||
}, | |||
cancelText: { | |||
type: String, | |||
default: '取消', | |||
}, | |||
confirmText: { | |||
type: String, | |||
default: '确定', | |||
}, | |||
headerPlaceholder: { | |||
type: String, | |||
default: '请输入关键字进行搜索', | |||
}, | |||
isSearch: { | |||
type: [Boolean, String], | |||
default: false, | |||
}, | |||
isHeader: { | |||
type: [Boolean, String], | |||
default: true, | |||
}, | |||
isSearchFun: { | |||
type: [Boolean, String], | |||
default: false, | |||
}, | |||
alls: { | |||
type: [Boolean, String], | |||
default: false, | |||
}, | |||
isLoading: { | |||
type: [Boolean, String], | |||
default: false, | |||
}, | |||
}, | |||
watch: { | |||
list() { | |||
this.loading = false | |||
this.popList = JSON.parse(JSON.stringify(this.list)) | |||
this.setList() | |||
}, | |||
value() { | |||
this.popList = JSON.parse(JSON.stringify(this.list)) | |||
this.setList() | |||
}, | |||
}, | |||
// 数据说明 | |||
/* list 传进来的数据 | |||
* popList 可以选择的数据 | |||
* result 当前选中的数据 ,key 数组 | |||
* ListJz 确定选择的数据 ,key 数组 | |||
* ListXz 确定选择的数据 ,全数组 | |||
* | |||
*/ | |||
data() { | |||
return { | |||
loading: false, | |||
finished: false, | |||
popList: [], | |||
ListJz: [], | |||
ListXz: [], | |||
primary: "#f39800", | |||
result: [], | |||
KeyType: false, | |||
valueType: false, | |||
valueTypeObject: false, | |||
showPicker: false, | |||
eWidth: 0, | |||
inpeWidth: '', | |||
inpeWidthLfet: '', | |||
labelWidths: '90px', | |||
key: '', | |||
resultRadio: '' | |||
} | |||
}, | |||
created() { | |||
this.loading = false | |||
this.popList = JSON.parse(JSON.stringify(this.list)) | |||
this.setList() | |||
}, | |||
mounted() {}, | |||
methods: { | |||
getChecked(code) { | |||
return this.result.some(el => { | |||
return el == code | |||
}) | |||
}, | |||
checkboxChange(evt) { | |||
this.result = evt.detail.value | |||
console.log(this.result) | |||
}, | |||
radioChange(evt) { | |||
this.result = [evt.detail.value] | |||
this.resultRadio = evt.detail.value | |||
}, | |||
onSearch() { | |||
if (this.isSearchFun) { | |||
this.$emit('onSearch', this.key) | |||
} else { | |||
if (this.key) { | |||
this.popList = this.list.filter((el) => { | |||
return (this.KeyType ? el[this.showName] : el).indexOf(this.key) != -1 | |||
}) | |||
} else { | |||
this.popList = JSON.parse(JSON.stringify(this.list)) | |||
} | |||
} | |||
}, | |||
open() { | |||
if (!this.checkbox) { | |||
if (typeof this.value == 'string' || typeof this.value == 'number') { | |||
this.resultRadio = this.value | |||
} else { | |||
this.resultRadio = this.value[0] | |||
} | |||
} else { | |||
this.result = this.value | |||
} | |||
if (!this.disabled && !this.clickable) { | |||
this.showPicker = true | |||
} | |||
this.$emit('onOpen') | |||
}, | |||
close() { | |||
this.showPicker = false | |||
}, | |||
setList() { | |||
if (this.popList.length == 0) { | |||
if (this.disabled) { | |||
if (this.value) { | |||
if (this.checkbox) { | |||
this.ListXz = this.value | |||
} else { | |||
this.ListXz = [this.value] | |||
} | |||
} else { | |||
this.ListXz = [] | |||
} | |||
} | |||
return | |||
} | |||
if (this.popList.length > 0) { | |||
if (typeof this.popList[0] == 'object') { | |||
this.KeyType = true | |||
} else { | |||
this.KeyType = false | |||
} | |||
} | |||
if (typeof this.value == 'string' || typeof this.value == 'number') { | |||
this.valueType = false | |||
} else { | |||
this.valueType = true | |||
} | |||
if (typeof this.value == 'string' || typeof this.value == 'number') { | |||
this.result = this.value ? [JSON.parse(JSON.stringify(this.value))] : [] | |||
} else { | |||
let popList = this.value || [] | |||
this.result = popList.map((el) => { | |||
let a = el | |||
if (typeof a == 'object') { | |||
a = el[this.keys] | |||
} | |||
return a | |||
}) | |||
} | |||
this.ListJz = JSON.parse(JSON.stringify(this.result)) | |||
this.ListXz = [] | |||
this.popList.forEach((el, index) => { | |||
let type = this.result.some((a) => { | |||
let elc = this.KeyType ? el[this.keys] : el | |||
return elc == a | |||
}) | |||
if (type) { | |||
this.ListXz.push(JSON.parse(JSON.stringify(el))) | |||
} | |||
}) | |||
}, | |||
opened() { | |||
this.normal = false | |||
}, | |||
closed() { | |||
this.showPicker = false | |||
if (this.normal) { | |||
this.ListJz = JSON.parse(JSON.stringify(this.result)) | |||
} else { | |||
this.result = JSON.parse(JSON.stringify(this.ListJz)) | |||
} | |||
}, | |||
onCancel() { | |||
this.normal = false | |||
this.showPicker = false | |||
this.$emit('cancel') | |||
}, | |||
onConfirm() { | |||
if (this.required && this.result.length < 1) { | |||
this.$toast('您还未选择') | |||
return | |||
} | |||
this.ListXz = [] | |||
this.popList.forEach((el, index) => { | |||
let type = this.result.some((a) => { | |||
let elc = this.KeyType ? el[this.keys] : el | |||
return elc == a | |||
}) | |||
if (type) { | |||
this.ListXz.push(el) | |||
} | |||
}) | |||
this.normal = true | |||
let firm = null | |||
if (this.valueType) { | |||
//返回数组 valueType | |||
firm = this.result | |||
} else { | |||
if (this.result.length > 0) { | |||
firm = this.result[0] | |||
} else { | |||
firm = '' | |||
} | |||
} | |||
this.showPicker = false | |||
this.$emit('input', this.alls ? this.ListXz : firm) | |||
this.$emit('toConfirm', this.ListXz) | |||
let nameData = this.ListXz.length > 0 ? this.ListXz[0] : '' | |||
let valName = (typeof nameData == 'object') ? nameData[this.showName] : nameData | |||
this.$emit('update:valName', valName) | |||
}, | |||
dissatisfactionToggle(index) { | |||
if (!this.checkbox) { | |||
this.result = [] | |||
} | |||
this.$refs.dissatisfactionCheckboxes[index].toggle() | |||
}, | |||
}, | |||
mounted() { | |||
this.eWidth = this.$refs.echartsWrapper.clientWidth | |||
if (this.isLineFeed) { | |||
this.labelWidths = this.eWidth + 'px' | |||
} else { | |||
this.labelWidths = this.labelWidth | |||
} | |||
this.inpeWidth = this.label ? | |||
this.isLineFeed ? | |||
this.eWidth + 'px' : | |||
'calc(' + (this.eWidth - 12 + 'px') + ' - ' + this.labelWidth + ')' : | |||
this.eWidth + 'px' | |||
this.inpeWidthLfet = this.label ? | |||
this.isLineFeed ? | |||
this.eWidth + 'px' : | |||
'calc(' + (this.eWidth - 12 - 20 + 'px') + ' - ' + this.labelWidth + ')' : | |||
this.eWidth - 20 + 'px' | |||
}, | |||
} | |||
</script> | |||
<style scoped lang="scss"> | |||
.bottomPopup { | |||
position: fixed; | |||
left: 0; | |||
top: 0; | |||
bottom: 0; | |||
right: 0; | |||
z-index: 999; | |||
background-color: rgba(0, 0, 0, 0.5); | |||
.popup-content { | |||
position: fixed; | |||
left: 0; | |||
right: 0; | |||
bottom: 52px; | |||
// top: 0; | |||
background-color: #ffffff; | |||
} | |||
.slide-up-enter-active, | |||
.slide-up-leave-active { | |||
transition: all .3s ease; | |||
} | |||
.slide-up-enter, | |||
.slide-up-leave-to { | |||
transform: translateY(100%); | |||
} | |||
.uni-list-cell { | |||
padding: 12rpx 20rpx; | |||
border-bottom: 1px solid #f5f5f5; | |||
display: flex; | |||
justify-content: space-between; | |||
align-items: center; | |||
} | |||
.uni-list-cell:active { | |||
background-color: #f5f5f5; | |||
} | |||
} | |||
.loading { | |||
text-align: center; | |||
line-height: 80px; | |||
} | |||
.textR { | |||
text-align: right; | |||
} | |||
.noData { | |||
text-align: center; | |||
line-height: 40vh; | |||
color: #999; | |||
} | |||
.inputs { | |||
display: flex; | |||
justify-content: space-between; | |||
align-items: center; | |||
.arrows { | |||
width: 20px; | |||
font-size: 16px; | |||
margin-left: 4px; | |||
line-height: 25px; | |||
text-align: right; | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
color: #969799; | |||
} | |||
} | |||
.checkbox { | |||
line-height: 25px; | |||
// padding: 5px 0px; | |||
} | |||
.showData:active { | |||
background-color: #f9f9f9; | |||
} | |||
.showData { | |||
width: 100%; | |||
position: relative; | |||
.showData-field-input { | |||
line-height: 25px; | |||
display: flex; | |||
justify-content: space-between; | |||
align-items: flex-start; | |||
width: 100%; | |||
padding: 10px 0; | |||
.showData-field-label { | |||
margin-right: 12px; | |||
color: #969799; | |||
} | |||
.showData-field-pu::-webkit-scrollbar { | |||
display: none; | |||
/* Chrome Safari */ | |||
} | |||
.showData-field-pu { | |||
padding-right: 5px; | |||
color: #323233; | |||
font-size: 14px; | |||
overflow-y: hidden; | |||
overflow-x: auto; | |||
scrollbar-width: none; | |||
/* firefox */ | |||
-ms-overflow-style: none; | |||
/* IE 10+ */ | |||
white-space: nowrap; | |||
} | |||
} | |||
.showData-field-line { | |||
padding: 10px 0; | |||
line-height: 25px; | |||
width: 100%; | |||
.showData-field-label { | |||
margin-right: 12px; | |||
color: #969799; | |||
} | |||
.showData-field-pu::-webkit-scrollbar { | |||
display: none; | |||
/* Chrome Safari */ | |||
} | |||
.showData-field-pu { | |||
padding-right: 5px; | |||
color: #323233; | |||
font-size: 14px; | |||
overflow-y: hidden; | |||
overflow-x: auto; | |||
scrollbar-width: none; | |||
/* firefox */ | |||
-ms-overflow-style: none; | |||
/* IE 10+ */ | |||
white-space: nowrap; | |||
} | |||
} | |||
.color96 { | |||
color: #969799; | |||
} | |||
} | |||
.isLine::after { | |||
position: absolute; | |||
content: ' '; | |||
left: 0; | |||
right: 0; | |||
bottom: 0; | |||
border-bottom: 1px solid #ebedf0; | |||
-webkit-transform: scaleY(0.5); | |||
transform: scaleY(0.5); | |||
width: 100%; | |||
} | |||
.pop { | |||
&-header { | |||
height: 44px; | |||
border-bottom: 1px solid #ebedf0; | |||
background-color: #f7f8fa; | |||
align-items: center; | |||
display: flex; | |||
justify-content: center; | |||
font-size: 26rpx; | |||
&-left { | |||
width: 44px; | |||
text-align: center; | |||
color: #666; | |||
} | |||
&-right { | |||
width: 44px; | |||
text-align: center; | |||
} | |||
&-title { | |||
flex: 4; | |||
text-align: center; | |||
color: 32rpx; | |||
padding: 0 5px; | |||
} | |||
} | |||
&-main { | |||
overflow-x: hidden; | |||
overflow-y: auto; | |||
-webkit-overflow-scrolling: touch; | |||
scroll-behavior: smooth; | |||
height: 40vh; | |||
} | |||
} | |||
</style> |
@@ -0,0 +1,76 @@ | |||
<template> | |||
<div class="template"> | |||
<view class="cartoon" > | |||
<span class="char">拼</span> | |||
<span class="char">命</span> | |||
<span class="char">加</span> | |||
<span class="char">载</span> | |||
<span class="char">中</span> | |||
<span class="char">.</span> | |||
<span class="char">.</span> | |||
<span class="char">.</span> | |||
</view> | |||
</div> | |||
</template> | |||
<style lang="scss" scoped> | |||
.cartoon{ | |||
.char { | |||
display: inline-block; | |||
transform: translateY(8px); | |||
width: 20px; | |||
height: 20px; | |||
border-radius: 3px; | |||
animation: bounce 0.5s infinite alternate; | |||
} | |||
.char:nth-child(2) { | |||
animation-delay: 0.1s; | |||
} | |||
.char:nth-child(3) { | |||
animation-delay: 0.2s; | |||
} | |||
.char:nth-child(4) { | |||
animation-delay: 0.3s; | |||
} | |||
.char:nth-child(5) { | |||
animation-delay: 0.4s; | |||
} | |||
.char:nth-child(6) { | |||
animation-delay: 0.5s; | |||
} | |||
.char:nth-child(7) { | |||
animation-delay: 0.6s; | |||
} | |||
.char:nth-child(8) { | |||
animation-delay: 0.7s; | |||
} | |||
@keyframes bounce { | |||
0% { | |||
transform: translateY(8px); | |||
border-radius: 5px; | |||
} | |||
100% { | |||
transform: translateY(-8px); | |||
border-radius: 3px; | |||
} | |||
} | |||
} | |||
.template { | |||
padding: 20px; | |||
text-align: center; | |||
.loader { | |||
margin: 25px; | |||
} | |||
} | |||
</style> |
@@ -0,0 +1,78 @@ | |||
{ | |||
"id": "jp-select-plus", | |||
"displayName": "数据选择器、单选多选组件、弹框选择、可配置搜索", | |||
"version": "1.1", | |||
"description": "本组件是jp-select升级组件,该组件功能更强大,更方便。拥有 单选、多选、搜索、弹框选择、多选拼接展示...采用v-model双向绑定操作,用户使用更加方便", | |||
"keywords": [ | |||
"单选多选组件", | |||
"数据选择器", | |||
"弹出选择", | |||
"select", | |||
"搜索选择" | |||
], | |||
"engines": { | |||
"HBuilderX": "^3.1.0" | |||
}, | |||
"dcloudext": { | |||
"sale": { | |||
"regular": { | |||
"price": "0.00" | |||
}, | |||
"sourcecode": { | |||
"price": "0.00" | |||
} | |||
}, | |||
"contact": { | |||
"qq": "" | |||
}, | |||
"declaration": { | |||
"ads": "无", | |||
"data": "插件不采集任何数据", | |||
"permissions": "无" | |||
}, | |||
"type": "component-vue" | |||
}, | |||
"uni_modules": { | |||
"encrypt": [], | |||
"platforms": { | |||
"cloud": { | |||
"tcb": "y", | |||
"aliyun": "y" | |||
}, | |||
"client": { | |||
"App": { | |||
"app-vue": "y", | |||
"app-nvue": "y" | |||
}, | |||
"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", | |||
"阿里": "y", | |||
"百度": "y", | |||
"字节跳动": "y", | |||
"QQ": "y" | |||
}, | |||
"快应用": { | |||
"华为": "y", | |||
"联盟": "y" | |||
}, | |||
"Vue": { | |||
"vue2": "y", | |||
"vue3": "y" | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -0,0 +1,86 @@ | |||
<template> | |||
<view class="content"> | |||
<view class="hader">基础用法</view> | |||
<jp-select-plus label="单选不带搜索" placeholder="请选择" v-model="va1" :list="listc"></jp-select-plus> | |||
<jp-select-plus label="单选带搜索设置主题色" color="#f00"placeholder="请选择" isSearch v-model="va1" :list="listc"></jp-select-plus> | |||
<jp-select-plus label="多选带搜索-排列展示结果" placeholder="请选择" checkbox isSearch v-model="va2" :list="listc"></jp-select-plus> | |||
<jp-select-plus label="多选带搜索-拼接展示结果" placeholder="请选择" isJoin checkbox isSearch v-model="va2" :list="listc"></jp-select-plus> | |||
<jp-select-plus label="一行选择框" :isLineFeed="false" placeholder="请选择" isSearch v-model="va1" :list="listc"></jp-select-plus> | |||
<jp-select-plus label="改变选择主题颜色" placeholder="请选择" isSearch v-model="va1" :list="listc"></jp-select-plus> | |||
<view class="hader">进阶用法</view> | |||
<jp-select-plus @onOpen="getList()" @onSearch="getList()" label="点击后才去后端拿数据,展示加载中" isSearchFun isLoading placeholder="请选择" isSearch v-model="va1" :list="list2"></jp-select-plus> | |||
<view class="hader">只使用弹框</view> | |||
<view class="but" @click="toOpen"> | |||
点击开启弹框选择数据 | |||
</view> | |||
选中的数据:{{va3}} | |||
<jp-select-plus ref="selectPlus" :isShow="false" v-model="va3" :list="listc"></jp-select-plus> | |||
</view> | |||
</template> | |||
<script> | |||
export default { | |||
data() { | |||
return { | |||
va1: '', | |||
va2: [], | |||
va3: '', | |||
listc: [{ | |||
code: 'CHN', | |||
name: '中国' | |||
}, { | |||
name: '美国5', | |||
code: 'USA' | |||
}, { | |||
name: '巴西', | |||
code: 'BRA' | |||
}, { | |||
name: '日本', | |||
code: 'JPN' | |||
}, { | |||
name: '英国', | |||
code: 'ENG' | |||
}, { | |||
name: '法国', | |||
code: 'FRA' | |||
}, { | |||
name: '小人国', | |||
code: 'xr1' | |||
}, { | |||
name: '大人国', | |||
code: 'xr2' | |||
}, { | |||
name: '中人国中人国中人国中人国中人国中人国中人国中人国中人国中人国中人国', | |||
code: 'xr3' | |||
}], | |||
list2:[] | |||
} | |||
}, | |||
methods: { | |||
toOpen(){ | |||
this.$refs.selectPlus.open() | |||
}, | |||
getList(){ | |||
let that = this | |||
setTimeout(()=>{ | |||
that.list2 = that.listc | |||
},2000) | |||
} | |||
} | |||
} | |||
</script> | |||
<style scoped lang="scss"> | |||
.content { | |||
padding: 0 20px; | |||
.but{ | |||
margin: 10rpx 25rpx; | |||
background-color: #00aaff; | |||
color: #fff; | |||
text-align: center; | |||
line-height: 80rpx; | |||
} | |||
.hader { | |||
line-height: 80rpx; | |||
font-weight: 800; | |||
} | |||
} | |||
</style> |
@@ -0,0 +1,160 @@ | |||
## 阿里矢量图-图标组件 | |||
> **组件名:al-icon** | |||
### 安装方式 | |||
本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。 | |||
###本组件是jp-select 升级组件,该组件能满足大多数开发需求 | |||
####拥有 单选、多选、搜索、弹框选择、多选拼接展示...采用v-model双向绑定操作,用户使用更加方便 | |||
### 用法 | |||
```html | |||
<template> | |||
<view class="content"> | |||
<view class="hader">基础用法</view> | |||
<jp-select-plus label="单选不带搜索" placeholder="请选择" v-model="va1" :list="listc"></jp-select-plus> | |||
<jp-select-plus label="单选带搜索设置主题色" color="#f00"placeholder="请选择" isSearch v-model="va1" :list="listc"></jp-select-plus> | |||
<jp-select-plus label="多选带搜索-排列展示结果" placeholder="请选择" checkbox isSearch v-model="va2" :list="listc"></jp-select-plus> | |||
<jp-select-plus label="多选带搜索-拼接展示结果" placeholder="请选择" isJoin checkbox isSearch v-model="va2" :list="listc"></jp-select-plus> | |||
<jp-select-plus label="一行选择框" :isLineFeed="false" placeholder="请选择" isSearch v-model="va1" :list="listc"></jp-select-plus> | |||
<jp-select-plus label="改变选择主题颜色" placeholder="请选择" isSearch v-model="va1" :list="listc"></jp-select-plus> | |||
<view class="hader">进阶用法</view> | |||
<jp-select-plus @onOpen="getList()" @onSearch="getList()" label="点击后才去后端拿数据,展示加载中" isSearchFun isLoading placeholder="请选择" isSearch v-model="va1" :list="list2"></jp-select-plus> | |||
<view class="hader">只使用弹框</view> | |||
<view class="but" @click="toOpen"> | |||
点击开启弹框选择数据 | |||
</view> | |||
选中的数据:{{va3}} | |||
<jp-select-plus ref="selectPlus" :isShow="false" v-model="va3" :list="listc"></jp-select-plus> | |||
</view> | |||
</template> | |||
<script> | |||
export default { | |||
data() { | |||
return { | |||
va1: '', | |||
va2: [], | |||
va3: '', | |||
listc: [{ | |||
code: 'CHN', | |||
name: '中国' | |||
}, { | |||
name: '美国5', | |||
code: 'USA' | |||
}, { | |||
name: '巴西', | |||
code: 'BRA' | |||
}, { | |||
name: '日本', | |||
code: 'JPN' | |||
}, { | |||
name: '英国', | |||
code: 'ENG' | |||
}, { | |||
name: '法国', | |||
code: 'FRA' | |||
}, { | |||
name: '小人国', | |||
code: 'xr1' | |||
}, { | |||
name: '大人国', | |||
code: 'xr2' | |||
}, { | |||
name: '中人国中人国中人国中人国中人国中人国中人国中人国中人国中人国中人国', | |||
code: 'xr3' | |||
}], | |||
list2:[] | |||
} | |||
}, | |||
methods: { | |||
toOpen(){ | |||
this.$refs.selectPlus.open() | |||
}, | |||
getList(){ | |||
let that = this | |||
setTimeout(()=>{ | |||
that.list2 = that.listc | |||
},2000) | |||
} | |||
} | |||
} | |||
</script> | |||
<style scoped lang="scss"> | |||
.content { | |||
padding: 0 20px; | |||
.but{ | |||
margin: 10rpx 25rpx; | |||
background-color: #00aaff; | |||
color: #fff; | |||
text-align: center; | |||
line-height: 80rpx; | |||
} | |||
.hader { | |||
line-height: 80rpx; | |||
font-weight: 800; | |||
} | |||
} | |||
</style> | |||
``` | |||
## API | |||
### 参数 | |||
| 属性名 | 类型 | 默认值 | 说明 | | |||
| | | | | | |||
| list | Array| | 需要选择的数据(如果是对象需要配置 keys 和 showName 具体说明如下 ) | | |||
| keys| String | code | 需要识别的code标识 | | |||
| showName | String | name | 需要展示标识 | | |||
| v-model | | | 双向绑定 | | |||
| value | [String, Array] | | 初始值,多选时必须为数组 | | |||
| label | String | | label名称 | | |||
| labelColor | String | #646566 | label颜色 | | |||
| labelWidth|String| '90px'| label宽度(当选项为一行时生效) | | |||
| placeholder|String| '请选择'| placeholder | | |||
| placeholderColor|String| '#999'| placeholder字体颜色 | | |||
| isLineFeed|Boolean| true| 选项框是否为一行,默认独立开 | | |||
| required|Boolean| false| 是否显示必填 | | |||
| direction|String| left| 文字方向 默认左对齐 | | |||
| color|String|'#00aaff' | 主题色 | | |||
| alls|Boolean|false | 是否数据全部返回 | | |||
| isoverflow|Boolean|false | 超出隐藏 | | |||
| isJoin| Boolean|false | 多选时是否拼接展示 | | |||
| isLine|Boolean| true | 底部是否有线条 | | |||
| disabled|Boolean| fasle | 是否可以选择 | | |||
### 弹框参数 | |||
| 属性名 | 类型 | 默认值 | 说明 | | |||
| | | | | | |||
| title | String| 请选择 |弹框名称 | | |||
| cancelText| String | 取消 | 取消文字| | |||
| confirmText | String | 确定 | 确定文字 | | |||
| isSearch | Boolean| fasle | 是否开启头部搜索 | | |||
| isSearchFun | Boolean| fasle | 点击头部搜索是是否调用外部方法 | | |||
| isLoading | Boolean| fasle | 是否显示加载中 | | |||
### 事件 | |||
| 事件名 | 类型 | 回调参数 | 说明 | | |||
| | | | | | |||
| input | function |当前选择的数据 key 数组| | | |||
| toConfirm | function | 当前选择的数据 全数据 | 点击确认 | | |||
| onOpen | function |无 | 点击选择框时回调 | | |||
| cancel | function |无 | 点击取消 | | |||
| input | function |无 | e 当前选择的数据 key 数组 | | |||
### 方法 | |||
| 方法名| 说明 | | |||
| | | | |||
| open() | 打开弹框 | | |||
| close() | 关闭弹框 | | |||