You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

185 lines
3.8 KiB

<template>
<el-dialog
title="选择图标"
:visible.sync="dialogVisible"
width="600px"
:modal="true"
:close-on-click-modal="false"
:close-on-press-escape="false"
class="icon-select-dialog"
>
<div class="icon-grid">
<div
v-for="item in availableIcons"
:key="item.id"
class="icon-item"
:class="{ selected: selectedIcons.includes(item.id) }"
@click="toggleIcon(item)"
>
<i :class="item.icon"></i>
<span class="icon-name">{{ item.name }}</span>
<div v-if="selectedIcons.includes(item.id)" class="check-icon">
<i class="el-icon-check"></i>
</div>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="handleResetDefault" size="small" type="warning">恢复默认</el-button>
<el-button @click="dialogVisible = false" size="small">取消</el-button>
<el-button type="primary" @click="confirmAdd" size="small">确定</el-button>
</span>
</el-dialog>
</template>
<script>
export default {
name: 'IconSelectDialog',
props: {
visible: {
type: Boolean,
default: false
},
availableIcons: {
type: Array,
default: () => []
},
existingIcons: {
type: Array,
default: () => []
}
},
data() {
return {
selectedIcons: []
}
},
computed: {
dialogVisible: {
get() {
return this.visible
},
set(val) {
this.$emit('update:visible', val)
}
}
},
watch: {
visible(newVal) {
if (newVal) {
this.selectedIcons = []
}
}
},
methods: {
toggleIcon(item) {
const index = this.selectedIcons.indexOf(item.id)
if (index > -1) {
this.selectedIcons.splice(index, 1)
} else {
this.selectedIcons.push(item.id)
}
},
confirmAdd() {
const selectedItems = this.availableIcons.filter(item =>
this.selectedIcons.includes(item.id)
)
this.$emit('confirm', selectedItems)
this.dialogVisible = false
},
handleResetDefault() {
this.$confirm('确定要恢复默认图标配置吗?此操作将清空当前所有选择。', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$emit('reset-default')
this.dialogVisible = false
}).catch(() => {
})
}
}
}
</script>
<style scoped>
.icon-select-dialog >>> .el-dialog__body {
padding: 20px;
}
.icon-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
gap: 15px;
max-height: 400px;
overflow-y: auto;
}
.icon-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 15px 10px;
border: 2px solid #E4E7ED;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s;
position: relative;
background: white;
}
.icon-item:hover {
border-color: #008aff;
background: rgba(0, 138, 255, 0.05);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 138, 255, 0.15);
}
.icon-item.selected {
border-color: #008aff;
background: rgba(0, 138, 255, 0.1);
}
.icon-item i {
font-size: 28px;
color: #555;
margin-bottom: 8px;
transition: color 0.3s;
}
.icon-item:hover i,
.icon-item.selected i {
color: #008aff;
}
.icon-name {
font-size: 12px;
color: #606266;
text-align: center;
word-break: break-all;
}
.check-icon {
position: absolute;
top: 5px;
right: 5px;
width: 20px;
height: 20px;
border: 2px solid #008aff;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: #008aff;
font-size: 12px;
}
.dialog-footer {
display: flex;
justify-content: flex-end;
gap: 10px;
}
</style>