本组件适用于公司项目,提供组件代码为开发者提供思路进而可进行开发 Tree 树形控件 等递归组件
案例:
代码部分: index.vue
<template>
<div v-clickoutside="clickOutside" class="cascader-box" :class="`cascader-${props.theme} cascader-${props.size}`">
<div ref="headerSelectRef" class="header-box">
<div class="header-type-one" :class="{'active': isShowList}" :style="{'width':width,'height':inputHeight,'padding-left': selectDataTitle.length>0 && !isAllCheackboxed ? '6px' : ''}" @click="showCascaderList">
<div class="content-flex-shink">
<template v-if="selectType == '0'">
<span v-if="selectDataTitle.length<=0" class="title">{{ placeholder }}</span>
<span v-else-if="!isAllCheackboxed" class="select-title">
<span ref="selectName" class="select-name">
<span>{{selectDataTitle[0][label]}}</span>
</span>
<span v-show="selectDataTitle.length - 1 > 0" ref="selectNumber" class="select-number">
<span class="add-font">+</span><span>{{selectDataTitle.length - 1}}</span>
</span>
</span>
<span v-else class="select-title">
<span>{{props.defaultAllName}}</span>
</span>
</template>
<template v-if="selectType == '1'">
<span v-if="selectDataTitle.length<=0" class="title">{{ placeholder }}</span>
<span v-else-if="!isAllCheackboxed" class="select-title">
<span class="select-name-2">
<span class="show-str-content">{{ selectTypeDataType1 }}</span>
<span class="clear-icon-type1" @click.stop="clearSelect"></span>
</span>
</span>
<span v-else class="select-title">
<span>{{props.defaultAllName}}</span>
</span>
</template>
</div>
<div class="cascader-select-arrow" :class="{'activeList': isShowList}"></div>
</div>
</div>
<div v-show="isShowList" ref="emListPopper" class="list-select-box">
<cascaderNode
ref="cascaderNodeRef"
:nodes="nodes"
:props="props"
:child-name="childName"
:label="label"
:level="0"
:changefunction="changeCheackBox"
></cascaderNode>
</div>
</div>
</template>
<script setup lang="ts">
import vClickoutside from '../../../directives/clickoutside'
import _ from 'lodash';
import {ref,watch,nextTick} from 'vue';
import { createPopper, PositioningStrategy } from '@popperjs/core';
import cascaderNode from './cascader-node.vue';
const EMSetting = {
debounce:(
function () {
let t:any = null;
return (fn:Function, delay:number)=>{
if (t !== null) {
clearTimeout(t)
}
t = setTimeout(() => {
fn()
}, delay);
}
}
)()
}
interface item {
[key: string]: string | boolean | any;
}
interface IProps {
theme?:string;
dataType?: string;
strategy?: string,
selectType?: string;
width?: string;
inputHeight?: string;
height?:string;
liWidth?:string;
size?:string;
nodes?: item[];
isCheckAll?: boolean;
field?: string;
childName?: string;
label?: string;
defaultAllName?: string;
placeholder?: string;
hoverTitle?: boolean;
isShowAllRow?: boolean;
asyncRequestFunction?:Function;
isResSelected?: boolean;
onlyShowLastNode?: boolean;
isCloseSubmit?: boolean;
}
let props = withDefaults(defineProps<IProps>(), {
theme:'white', // white 白色(默认) black黑色
dataType:'all', // 传入数据类型 all 全部数据(默认值) async异步数据
strategy: 'absolute', // popper定位
selectType: '1', // 0 名字 剩余显示 + n(默认0) 1 名字累加
width: '130px', // 选择框宽度
inputHeight: '', // 选择框高度度
height: '200px', // 选项高度 大屏默认 200px 小屏 180px 超出加滚动条
liWidth:'130px', // 级联内容选项列宽
size: 'large', // large small
nodes: () => { return [];}, // 数据
isCheckAll: false, // 是否勾选所有
field: '', // 返回数据code key
childName: 'children', // 子级节点名字
label: 'name', // 显示字段key
defaultAllName:'全部', // 选项全部,和选择结果全部 更改名字
placeholder: '请选择', // 选择框默认显示 默认显示
hoverTitle: true, // 移动上去是否显示提示
isShowAllRow: true ,// 是否(显示勾选项中 全部 )
asyncRequestFunction: undefined, // 异步请求节点 传入回调方法
isResSelected: false, // 是否返回处理之后的勾选的结果 以二维数组进行返回
isCloseSubmit: true, // 是否关闭提交数据
onlyShowLastNode: false // 是否只返回最后一层数据
})
const emitEvent = defineEmits(['submitCascader','emitClearSelect']) // submitCascader 通知数据 emitClearSelect 清空时候通知
let isShowList = ref<boolean>(false) // 下拉项显示状态
let cheackboxedArray = ref<any[]>([]) // 选中的数据
let isAllCheackboxed = ref<boolean>(false) // 全部选中 状态值
let selectDataTitle = ref<any[]>([]) // 选择框展示的勾选数据
let selectTypeDataType1 = ref<string>('') // selectType 展示类型为1情况下
let cascaderNodeRef = ref() // 组件 ref
let popperInstance = ref() // popper 实例
let headerSelectRef = ref<HTMLElement | null>(null);
let emListPopper = ref<HTMLElement | null>(null);
const popperEvent = ()=>{
popperInstance.value = createPopper(headerSelectRef.value as HTMLElement, emListPopper.value as HTMLElement, {
//位置:从下面开始
placement: 'bottom-start',
modifiers: [
{
name: 'offset',
options: {
// xy为左右和上下的offset
offset: [0, 8]
}
},
{
name: 'preventOverflow',
options: {
mainAxis: false
}
}
],
strategy: props.strategy as PositioningStrategy
});
}
// 勾选改变触发 进行勾选项实时显示
const changeCheackBox = (isEmit:boolean)=>{
EMSetting.debounce(()=>{
cheackboxedArray.value = []
for (let i = 0; i < props.nodes.length; i++) {
let currentData = props.nodes[i];
if(!cheackboxedArray.value[0]){
cheackboxedArray.value[0] = []
}
if (['1','2'].includes(currentData.selectType)) {
if(currentData.selectType == '2') {
if(props.onlyShowLastNode) {
if(props.dataType == 'async') {
if(!currentData.isShowMore) {
cheackboxedArray.value[0].push(currentData)
}
}else if(!currentData[props.childName] || currentData[props.childName].length <= 0 ) {
cheackboxedArray.value[0].push(currentData)
}
}else{
cheackboxedArray.value[0].push(currentData)
}
}
if(currentData[props.childName] && currentData[props.childName].length > 0) {
findCheackBoxed(currentData[props.childName],1)
}
}
}
if(props.nodes.length == cheackboxedArray.value[0].length) {
isAllCheackboxed.value = true
}else{
isAllCheackboxed.value = false
}
selectDataTitle.value = _.cloneDeep(cheackboxedArray.value.flat())
handleDataEvent(isEmit)
},200)
}
interface SendData {
[key: string]: string | boolean | any;
}
let sendData = ref<SendData>(
{
data: [], // 勾选数据
isAll: isAllCheackboxed.value // 是否全部勾选
}
)
// 显示下拉项 更新下拉项位置
const showCascaderList = ()=>{
isShowList.value = true
nextTick(()=>{
popperEvent()
})
}
// 点击其它区域关闭下拉项
const clickOutside = ()=>{
isShowList.value = false
if(props.isCloseSubmit) {
emitEvent('submitCascader',sendData.value)
}
}
// 处理勾选数据,得到勾选项
const handleDataEvent = (isEmit:boolean)=>{
if(props.isResSelected) {
if(props.onlyShowLastNode) {
if(props.field) {
let flatArray = cheackboxedArray.value.flat().map(item=>{
return item[props.field]
})
sendData.value.data = flatArray
}else{
let flatArray = cheackboxedArray.value.flat()
sendData.value.data = flatArray
}
}else{
if(props.field) {
for (let i = 0; i < cheackboxedArray.value.length; i++) {
for (let j = 0; j < cheackboxedArray.value[i].length; j++) {
if(!sendData.value.data[i]) {
sendData.value.data[i] = []
}
sendData.value.data[i].push(cheackboxedArray.value[i][j][props.field])
}
}
}else{
sendData.value.data = cheackboxedArray.value
}
}
}else{
sendData.value.data = props.nodes
}
if(!props.isCloseSubmit || isEmit) {
emitEvent('submitCascader',sendData.value)
}
}
const findCheackBoxed = (data:any,index:number)=>{
if(!cheackboxedArray.value[index]){
cheackboxedArray.value[index] = []
}
for (let i = 0; i < data.length; i++) {
let currentData = data[i];
if (['1','2'].includes(currentData.selectType)) {
if(currentData.selectType == '2') {
if(props.onlyShowLastNode) {
if(props.dataType == 'async') {
if(!currentData.isShowMore) {
cheackboxedArray.value[index].push(currentData)
}
}else if(!currentData[props.childName] || currentData[props.childName].length <= 0 ) {
cheackboxedArray.value[index].push(currentData)
}
}else{
cheackboxedArray.value[index].push(currentData)
}
}
if(currentData[props.childName] && currentData[props.childName].length > 0) {
findCheackBoxed(currentData[props.childName],index+1)
}
}
}
}
// 清空勾选
const clearSelect = ()=>{
updataListState('0')
emitEvent('emitClearSelect')
}
// 全部选中
const checkAllFunction = ()=>{
updataListState('2')
}
// 更新勾选状态
const updataListState = (state:string)=>{
if(cascaderNodeRef.value) {
cascaderNodeRef.value.cheackAllEvent(state)
}
}
// 设置初始勾选 用于外部调用初始化勾选项
const setInitCheckState = ()=>{
// true 用于传入初始化勾选时候通知勾选数据
changeCheackBox(true)
}
// 监听结果展示选中展示项
let selectName = ref()
let selectNumber = ref()
watch(selectDataTitle,()=>{
if(props.selectType == '0' && selectDataTitle.value.length > 0 && !isAllCheackboxed.value) {
nextTick(()=>{
let widthVal = selectNumber.value?.clientWidth
selectName.value.style.width = `calc(100% - ${widthVal}px - 18px)`
})
}
if(props.selectType == '1' && selectDataTitle.value.length > 0 && !isAllCheackboxed.value) {
nextTick(()=>{
let nameArray:string[] = []
selectDataTitle.value.map(item=>{
nameArray.push(item[props.label])
})
selectTypeDataType1.value = nameArray.join(',')
})
}
})
watch(()=>props.isCheckAll,()=>{
if(props.isCheckAll) {
nextTick(()=>{
checkAllFunction()
})
}
},{
immediate: true
})
// 监听配置改变更新 popper
watch([
()=>props.width,
()=>props.inputHeight,
()=>props.height,
()=>props.liWidth,
()=>props.size
],()=>{
nextTick(()=>{
if(isShowList.value) {
popperEvent()
}
})
})
defineExpose({
clearSelect, // 清空所有
checkAllFunction, // 选中所有
setInitCheckState // s设置初始值
})
</script>
<style lang="scss" scoped>
@import "../style/index.scss";
</style>
递归子级代码:
<template>
<div class="cascader-node" :style="{'width':props.props.liWidth}" :class="[level == 0 ? '':'otherDom']">
<div class="content-box" :style="{'height':props.props.height}">
<!--active 点击选择 -->
<div v-if="level == 0 && props.props.isShowAllRow" class="list-box" :class="{'allCheackBox': isCheackBoxAll}" @click="cheackAllEvent('')">
<div class="left-content">
<div class="cheackbox" :class="{'active': isCheackBoxAll}"></div>
<div class="name" >{{ props.props.defaultAllName }}</div>
</div>
</div>
<div v-for="(child,index) in nodes" :key="index" class="list-box" :class="{'active': activeIndex == index && child.isShowChild}">
<div class="left-content" @click.stop="getSelectVal(child,index)">
<!-- active1 半选 active全选 -->
<div class="cheackbox" :class="getCurrentActiveName(child)" @click.stop="cheackboxEvent(child)"></div>
<div class="name" :title="props.props.hoverTitle ? child[props.label] : ''" :class="getCurrentFontColor(child,level)">{{child[props.label]}}</div>
</div>
<div v-if="(child[childName] && child[childName].length>0) || child.isShowMore" class="more" @click.stop="getSelectVal(child,index)"></div>
</div>
</div>
<div v-if="activeIndex != null && nodes[activeIndex].isShowChild && nodes[activeIndex][childName] && nodes[activeIndex][childName].length > 0" class="children">
<cascaderNode
ref="cascaderNode"
:nodes="nodes[activeIndex][childName]"
:child-name="childName"
:label="label"
:level="level+1"
:props="props.props"
:changefunction="props.changefunction"
@updataCheackBox="updataCheackBoxEvent"
></cascaderNode>
</div>
</div>
</template>
<script setup lang="ts">
import {computed, ref,nextTick} from 'vue';
interface item {
[key: string]: string | boolean | any;
}
interface IProps {
nodes?: item[];
level?: number;
childName?: string;
label?: string,
props?: any,
changefunction?:Function
}
let props = withDefaults(defineProps<IProps>(), {
nodes:() => {
return [];
},
level:0,
childName: 'children',
label: 'name',
props: ()=>{return {}},
changefunction: ()=>{
return ()=>{}
}
})
const emitEvent = defineEmits(['updataCheackBox'])
let activeIndex = ref<number|null>(null)
// 选项点击事件
const getSelectVal = async (item:any,index:number)=>{
if(props.props.dataType == 'async' && item.isShowMore && (!item[props.childName] || item[props.childName].length <= 0)) {
// 异步数据,没有请求过情况
let getCurrentChildrenNodes = await props.props.asyncRequestFunction(item)
item[props.childName] = getCurrentChildrenNodes
item.selectType = item.selectType ? item.selectType : '0'
cheackboxEvent(item,item.selectType)
}
if((!item[props.childName] || item[props.childName].length <= 0) || !item.isShowMore) {
cheackboxEvent(item)
}
activeIndex.value = index
item.isShowChild = true
for (let i = 0; i < props.nodes.length; i++) {
if(props.nodes[i].isShowChild && i != index) {
// eslint-disable-next-line vue/no-mutating-props
props.nodes[i].isShowChild = false
childStatus(props.nodes[i])
}
}
nextTick(()=>{
let boxEle = document.querySelector('.list-select-box') as HTMLElement
let widthVal = parseFloat(props.props.liWidth)
if(boxEle.querySelectorAll('.children') && boxEle.querySelectorAll('.children').length > 0) {
let lengthVal = boxEle.querySelectorAll('.children').length
boxEle.style.width = (lengthVal+1)*widthVal + 'px'
}else{
boxEle.style.width = widthVal + 'px'
}
})
}
const childStatus = (item:any)=>{
if(!item[props.childName] || item[props.childName] <= 0) {
return
}
for (let i = 0; i < item[props.childName].length; i++) {
let itemChild = item[props.childName][i]
if(itemChild.isShowChild) {
itemChild.isShowChild = false
childStatus(itemChild)
break
}
}
}
// 选中 半选 不选 图标 class
const getCurrentActiveName = (item:any)=>{
let classActiveName:String = ''
switch (item.selectType) {
case '0':
classActiveName = ''
break;
case '1':
classActiveName = 'active1'
break;
case '2':
classActiveName = 'active'
break;
default:
break;
}
return classActiveName
}
// 处理最后一层 选中 时候 文字高亮
const getCurrentFontColor = (item:any,level:number)=>{
if(level>0 && (!item[props.childName] || item[props.childName].length<=0) && item.selectType == '2') {
return 'activeName'
}
}
// 勾选事件
const cheackboxEvent = (item:any,setSelectType?:string)=>{
if(setSelectType) {
item.selectType = setSelectType
}else{
item.selectType = item.selectType == '2' ? '0' : '2'
}
// 通知子级
if(item[props.childName] && item[props.childName].length > 0) {
for (let i = 0; i < item[props.childName].length; i++) {
item[props.childName][i].selectType = item.selectType
mapActiveSate(item)
break
}
}
// 通知父级
emitEvent('updataCheackBox',props.nodes)
// 通知勾选触发了
nextTick(()=>{
// 勾选后通知改变,异步请求时候非勾选情况下需要通知,因 可能节点勾选 子节点需要进行勾选上
if(!setSelectType || setSelectType != '0') {
props.changefunction()
}
})
}
const mapActiveSate = (item:any)=>{
if(item[props.childName] && item[props.childName].length > 0) {
for (let i = 0; i < item[props.childName].length; i++) {
item[props.childName][i].selectType = item.selectType
mapActiveSate(item[props.childName][i])
}
}
}
const updataCheackBoxEvent = (data:any)=>{
let isChildrenAllActive = data.every((v:any)=>{
return v.selectType == '2'
})
let isChildrenSomeActive = data.some((v:any)=>{
return v.selectType == '2' || v.selectType == '1'
})
if(activeIndex.value != null) {
if(isChildrenAllActive) {
// eslint-disable-next-line vue/no-mutating-props
props.nodes[activeIndex.value].selectType = '2'
}else{
if(isChildrenSomeActive) {
// eslint-disable-next-line vue/no-mutating-props
props.nodes[activeIndex.value].selectType = '1'
}else{
// eslint-disable-next-line vue/no-mutating-props
props.nodes[activeIndex.value].selectType = '0'
}
}
}
emitEvent('updataCheackBox',props.nodes)
}
// 全部功能
let isCheackBoxAll = computed(()=>{
let isAllCheack = false
if(props.level == 0) {
isAllCheack = props.nodes.every((item:any)=>{
return item.selectType == '2'
})
}
return isAllCheack
})
// 全部 点击事件
const cheackAllEvent = (state?:string)=>{
let cheackBoxType;
if(state) {
cheackBoxType = state
}else{
cheackBoxType = isCheackBoxAll.value ? '0' : '2'
}
for (let i = 0; i < props.nodes.length; i++) {
let currentVal = props.nodes[i]
currentVal.selectType = cheackBoxType
closeChildCheack(currentVal,cheackBoxType)
}
nextTick(()=>{
props.changefunction()
})
}
const closeChildCheack = (item:any,state:string)=>{
if(!item[props.childName] || item[props.childName].length <= 0) {
item.selectType = state
return
}else{
for (let i = 0; i < item[props.childName].length; i++) {
let itemChild = item[props.childName][i]
itemChild.selectType = state
closeChildCheack(itemChild,state)
}
}
}
defineExpose({
cheackAllEvent
})
</script>
<style lang="scss" scoped>
@import "../style/index.scss";
</style>
scss: 组件图片使用时候可自己替换几个图片保证能组件能使用
.cascader-large {
--font-size: 14px;
--header-type-one-width: 130px;
--header-type-one-height: 32px;
--header-type-one-padding: 0px 8px 0px 12px;
--list-box-padding: 0px 12px;
--list-box-height: 28px;
--cheackbox-width: 14px;
--cheackbox-after-width: 6px;
--cheackbox-after-height: 9px;
--more-width:7px;
--more-height:7px;
--name-width: calc(100% - 14px);
--select-name-height: 24px;
--select-name-padding: 6px;
--select-number-margin-left: 6px;
--select-number-padding: 6px;
--select-number-add-font: 0px;
--select-number-add-font-width: 18px;
--select-name-2-width: calc(100% - 12px);
--clear-icon: 14px; // 删除按钮大小
--selsect-clear-icon-position: 4px 50%; // 删除按钮位置
--clear-icon-type1-min-width: 18px;
--scrollbar-width: 8px;
--scrollbar-height: 8px;
}
.cascader-small {
--font-size: 12px;
--header-type-one-width: 105px;
--header-type-one-height: 24px;
--header-type-one-padding: 0px 8px 0px 8px;
--list-box-padding: 0px 8px;
--list-box-height: 24px;
--cheackbox-width: 12px;
--cheackbox-after-width: 5px;
--cheackbox-after-height: 8px;
--more-width: 6px;
--more-height: 6px;
--name-width: calc(100% - 12px);
--select-name-height: 18px;
--select-name-padding: 4px;
--select-number-margin-left: 4px;
--select-number-padding: 4px;
--select-number-add-font: -2px;
--select-number-add-font-width: 15px;
--select-name-2-width: calc(100% - 18px);
--clear-icon: 10px;
--selsect-clear-icon-position: 4px 50%;
--clear-icon-type1-min-width: 14px;
--scrollbar-width: 6px;
--scrollbar-height: 6px;
}
.cascader-white {
--header-type-one-bg: #f8f8f8;
--content-flex-shink-title-color: #999999;
--cascader-select-arrow-color: transparent #222 #222 transparent;
--cascader-select-hover-border-color: #ff6600;
--cascader-select-active-border-color: #ff6600;
--cascader-select-active-bg: #ffffff;
--cascader-node-bg: #ffffff;
--cheackbox-bg: #ffffff;
--cheackbox-border-color: #e1e1e1;
--cheackbox-hover-color: #ff6600;
--cheackbox-active-bg-color: #ff6600;
--cheackbox-active-after-border-color: #ff6600;
--cheackbox-active1-bg-color: #ff6600;
--more-before-border-color: #222 #222 transparent transparent;
--content-box-hover-bg: #fff6f0;
--content-box-active-bg: #fff6f0;
--content-box-active-name: #ff6600;
--content-box-active-more: #ff6600 #ff6600 transparent transparent;
--allCheackBox-name: #ff6600;
--allCheackBox-more-before: #ff6600 #ff6600 transparent transparent;
--otherDom-border-color: #e1e1e1;
--left-content-name-color: #222222;
--left-content-active-name-color: #ff6600;
--scroll-bar-bg: #e1e1e1; // 滚动条颜色
--clear-icon-url: url("../../images/white-clear-normal.svg") no-repeat; // 清除图标
--clear-icon-hover-url: url("../../images/white-clear-hover.svg") no-repeat; // 清除图标hover
--select-name-2-bg: #ececec;
--select-name-2-border-color: #e1e1e1;
--select-name-2-font-color: #222222;
}
.cascader-black {
--header-type-one-bg: #3b3d41;
--content-flex-shink-title-color: #999999;
--cascader-select-arrow-color: transparent #fff #fff transparent;
--cascader-select-hover-border-color: #00a0e9;
--cascader-select-active-border-color: #00a0e9;
--cascader-select-active-bg: #27282c;
--cascader-node-bg: #3b3d41;
--cheackbox-bg: #3b3d41;
--cheackbox-border-color: #65686d;
--cheackbox-hover-color: #00a0e9;
--cheackbox-active-bg-color: #00a0e9;
--cheackbox-active-after-border-color: #00a0e9;
--cheackbox-active1-bg-color: #00a0e9;
--more-before-border-color: #fff #fff transparent transparent;
--content-box-hover-bg: #46484d;
--content-box-active-bg: #46484d;
--content-box-active-name: #00a0e9;
--content-box-active-more: #00a0e9 #00a0e9 transparent transparent;
--allCheackBox-name: #00a0e9;
--allCheackBox-more-before: #00a0e9 #00a0e9 transparent transparent;
--otherDom-border-color: #4c4e52;
--left-content-name-color: #ffffff;
--left-content-active-name-color: #00a0e9;
--scroll-bar-bg: #595a5c; // 滚动条颜色
--clear-icon-url: url("../../images/black-clear-normal.svg") no-repeat; // 清除图标
--clear-icon-hover-url: url("../../images/black-clear-hover.svg") no-repeat; // 清除图标hover
--select-name-2-bg: #4d4d4d;
--select-name-2-border-color: #4d4d4d;
--select-name-2-font-color: #ffffff;
}
.cascader-box {
// 头部筛选框
width: fit-content;
.header-box {
width: fit-content;
.header-type-one {
width: var(--header-type-one-width);
height: var(--header-type-one-height);
background-color: var(--header-type-one-bg);
border-radius: 4px;
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--header-type-one-padding);
box-sizing: border-box;
border: 1px solid var(--header-type-one-bg);
.content-flex-shink {
height: 100%;
width: 100%;
overflow: hidden;
.title {
height: 100%;
display: flex;
align-items: center;
font-size: var(--font-size);
color: var(--content-flex-shink-title-color);
}
.select-title{
width: 100%;
height: 100%;
display: inline-block;
box-sizing: border-box;
display: flex;
align-items: center;
.select-name{
display: inline-block;
width: fit-content;
height: var(--select-name-height);
display: inline-block;
background-color: #ececec;
box-sizing: border-box;
border-radius: 4px;
border: solid 1px #e1e1e1;
padding: var(--select-name-padding);
display: flex;
align-items: center;
span {
width: 100%;
word-break: break-all;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: var(--font-size);
}
}
.select-number{
display: inline-block;
margin-left: var(--select-number-margin-left);
min-width: 40px;
width: fit-content;
height: var(--select-name-height);
padding: var(--select-number-padding);
background-color: #ececec;
border-radius: 4px;
border: solid 1px #e1e1e1;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
span{
width: 100%;
word-break: break-all;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: var(--font-size);
}
.add-font{
width:var(--select-number-add-font-width);
font-size: var(--font-size);
margin-top: var(--select-number-add-font);
}
}
.select-name-2{
display: inline-block;
width: var(--select-name-2-width);
height: var(--select-name-height);
display: inline-block;
background-color: var(--select-name-2-bg);
box-sizing: border-box;
border-radius: 4px;
border: solid 1px var(--select-name-2-border-color);
padding: var(--select-name-padding);
display: flex;
align-items: center;
.show-str-content {
width: 100%;
word-break: break-all;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: var(--font-size);
color: var(--select-name-2-font-color);
}
.clear-icon-type1{
width: 8%;
min-width: var(--clear-icon-type1-min-width);
height: inherit;
display: flex;
justify-content: center;
align-items: center;
padding: 0px 4px 0px 4px;
background: var(--clear-icon-url);
background-size: var(--clear-icon);
background-position: var(--selsect-clear-icon-position);
&:hover {
background: var(--clear-icon-hover-url);
background-size: var(--clear-icon);
background-position: var(--selsect-clear-icon-position);
}
}
}
}
}
.cascader-select-arrow {
position: relative;
&::before {
content: "";
position: absolute;
width: 6px;
height: 6px;
right: 0;
top: 50%;
border-color: var(--cascader-select-arrow-color);
border-style: solid;
border-width: 1px;
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
margin-top: -5px;
-webkit-transition: all .4s;
transition: all .4s;
}
&.activeList::before {
margin-top: -1px;
transform: rotate(-135deg);
}
}
&:hover {
cursor: pointer;
border: solid 1px var(--cascader-select-hover-border-color);
}
&.active {
border: solid 1px var(--cascader-select-active-border-color);
background: var(--cascader-select-active-bg);
}
}
}
.list-select-box {
position: relative;
box-shadow: 0px 1px 12px 0px rgba(0, 0, 0, 0.1);
z-index: 100;
.cascader-node {
display: flex;
height: 100%;
background-color: var(--cascader-node-bg);
border-radius: 4px 0px 0px 4px;
box-sizing: border-box;
.content-box {
width: 100%;
height: 100%;
flex-shrink: 0;
padding: 4px 0px;
overflow-y: auto;
&::-webkit-scrollbar {
width: var(--scrollbar-width);
height: var(--scrollbar-height);
}
&::-webkit-scrollbar-thumb {
background: var(--scroll-bar-bg);
border-radius: 4px;
}
&::-webkit-scrollbar-track-piece {
background: transparent;
}
.list-box {
display: flex;
padding: var(--list-box-padding);
box-sizing: border-box;
height: var(--list-box-height);
align-items: center;
justify-content: space-between;
.left-content {
display: flex;
align-items: center;
width: calc(100% - 8px);
.cheackbox {
width: var(--cheackbox-width);
height: var(--cheackbox-width);
background-color: var(--cheackbox-bg);
border-radius: 2px;
border: solid 1px var(--cheackbox-border-color);
&:hover {
border: solid 1px var(--cheackbox-hover-color);
}
&.active {
position: relative;
border: solid 1px var(--cheackbox-hover-color);
background: var(--cheackbox-active-bg-color);
&::after {
content: "";
position: absolute;
left: 50%;
top: 0;
width: var(--cheackbox-after-width);
height: var(--cheackbox-after-height);
border: solid 2px var(--cheackbox-active-after-border-color);
border-bottom-color: #ffffff;
border-right-color: #ffffff;
-webkit-transform: translate(-50%, 0%) rotate(45deg);
transform: translate(-50%, 0%) rotate(45deg);
}
}
&.active1 {
position: relative;
&::after {
content: "";
position: absolute;
left: 50%;
top: 50%;
width: 7px;
height: 6px;
background-color: var(--cheackbox-active1-bg-color);
border-radius: 1px;
transform: translate(-50%, -50%);
box-sizing: border-box;
}
}
}
.name {
padding-left: 4px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: var(--name-width);
font-size: var(--font-size);
color: var(--left-content-name-color);
}
.activeName{
color: var(--left-content-active-name-color);
}
}
.more {
position: relative;
&::before {
content: "";
position: absolute;
right: 8px;
top: 50%;
width: var(--more-width);
height: var(--more-height);
border-color: var(--more-before-border-color);
border-style: solid;
border-width: 1.5px;
box-sizing: border-box;
-webkit-transform: translate(50%, -50%) rotate(45deg);
transform: translate(50%, -50%) rotate(45deg);
z-index: 2;
}
}
&:hover {
background-color: var(--content-box-hover-bg);
}
&.active {
background-color: var(--content-box-active-bg);
.name {
color: var(--content-box-active-name);
}
.more {
&::before {
border-color: var(--content-box-active-more);
}
}
}
}
.allCheackBox {
.name {
color: var(--allCheackBox-name);
font-size: var(--font-size);
}
.more {
&::before {
border-color: var(--allCheackBox-more-before);
}
}
}
}
}
.otherDom {
height: 100%;
margin-top: 0px;
border-radius: 0px;
border-left: 1px solid var(--otherDom-border-color);
box-sizing: border-box;
}
}
}