Demo:节点图标/贴纸侧边栏优化,支持快速定位到指定类型的素材

This commit is contained in:
街角小林 2025-04-25 09:26:37 +08:00
parent 4de35fca9c
commit 1859e0a8e8

View File

@ -1,20 +1,41 @@
<template>
<Sidebar ref="sidebar" :title="$t('nodeIconSidebar.title')">
<div class="box" :class="{ isDark: isDark }">
<el-tabs v-model="activeName">
<el-tab-pane
:label="$t('nodeIconSidebar.icon')"
name="icon"
></el-tab-pane>
<el-tab-pane
:label="$t('nodeIconSidebar.sticker')"
name="image"
></el-tab-pane>
</el-tabs>
<div class="boxContent">
<div class="box " :class="{ isDark: isDark }">
<div class="boxHeader">
<el-tabs v-model="activeName">
<el-tab-pane
:label="$t('nodeIconSidebar.icon')"
name="icon"
></el-tab-pane>
<el-tab-pane
:label="$t('nodeIconSidebar.sticker')"
name="image"
></el-tab-pane>
</el-tabs>
<el-select
size="mini"
style="width: 100%; margin-bottom: 10px;"
v-model="currentType"
@change="onCurrentTypeChange"
>
<el-option
v-for="item in typeSelectList"
:key="item.name"
:label="item.name"
:value="item.name"
>
</el-option>
</el-select>
</div>
<div class="boxContent customScrollbar" ref="boxContentRef">
<!-- 图标 -->
<div class="iconBox" v-if="activeName === 'icon'">
<div class="item" v-for="item in nodeIconList" :key="item.name">
<div
class="item"
v-for="item in nodeIconList"
:key="item.name"
:data-title="item.name"
>
<div class="title">{{ item.name }}</div>
<div class="list">
<div
@ -32,7 +53,12 @@
</div>
<!-- 贴纸 -->
<div class="imageBox" v-if="activeName === 'image'">
<div class="item" v-for="item in nodeImageList" :key="item.name">
<div
class="item"
v-for="item in nodeImageList"
:key="item.name"
:data-title="item.name"
>
<div class="title">{{ item.name }}</div>
<div class="list">
<div
@ -73,14 +99,19 @@ export default {
nodeImageList: [...image],
iconList: [],
nodeImage: '',
activeNodes: []
activeNodes: [],
currentType: ''
}
},
computed: {
...mapState({
activeSidebar: state => state.activeSidebar,
isDark: state => state.localConfig.isDark
})
}),
typeSelectList() {
return this.activeName === 'icon' ? this.nodeIconList : this.nodeImageList
}
},
watch: {
activeSidebar(val) {
@ -89,6 +120,11 @@ export default {
} else {
this.$refs.sidebar.show = false
}
},
activeName() {
this.currentType = ''
this.$refs.boxContentRef.scrollTop = 0
}
},
created() {
@ -164,6 +200,17 @@ export default {
...image
})
})
},
onCurrentTypeChange(val) {
const warp = this.$refs.boxContentRef
const elList = Array.from(warp.querySelectorAll('.item') || [])
const tar = elList.find(el => {
return el.getAttribute('data-title') === val
})
if (tar) {
warp.scrollTop = tar.offsetTop
}
}
}
}
@ -171,7 +218,10 @@ export default {
<style lang="less" scoped>
.box {
padding: 0 20px;
height: 100%;
overflow: hidden;
display: flex;
flex-direction: column;
&.isDark {
.title {
@ -179,6 +229,16 @@ export default {
}
}
.boxHeader {
width: 100%;
flex-shrink: 0;
padding: 0 20px;
/deep/ .el-tabs__header {
margin-bottom: 10px;
}
}
.title {
font-size: 16px;
font-weight: 500;
@ -186,11 +246,21 @@ export default {
}
.boxContent {
width: 100%;
height: 100%;
overflow-y: auto;
padding: 0 20px;
position: relative;
.iconBox {
.item {
margin-bottom: 20px;
font-weight: bold;
&:last-of-type {
margin-bottom: 0;
}
.title {
margin-bottom: 10px;
}
@ -238,6 +308,10 @@ export default {
margin-bottom: 20px;
font-weight: bold;
&:last-of-type {
margin-bottom: 0;
}
.title {
margin-bottom: 10px;
}