项目微调
This commit is contained in:
39
frontend/src/components/SelectIcon/index.scss
Normal file
39
frontend/src/components/SelectIcon/index.scss
Normal file
@@ -0,0 +1,39 @@
|
||||
.icon-box {
|
||||
width: 100%;
|
||||
.el-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 18px;
|
||||
color: var(--el-text-color-regular);
|
||||
}
|
||||
:deep(.el-dialog__body) {
|
||||
padding: 25px 20px 20px;
|
||||
.el-input {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.icon-list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, 115px);
|
||||
justify-content: space-evenly;
|
||||
max-height: 70vh;
|
||||
.icon-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 42px;
|
||||
padding: 20px 30px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
&:hover {
|
||||
transform: scale(1.3);
|
||||
}
|
||||
span {
|
||||
margin-top: 5px;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
89
frontend/src/components/SelectIcon/index.vue
Normal file
89
frontend/src/components/SelectIcon/index.vue
Normal file
@@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<div class='icon-box'>
|
||||
<el-input
|
||||
ref='inputRef'
|
||||
v-model='valueIcon'
|
||||
v-bind='$attrs'
|
||||
:placeholder='placeholder'
|
||||
:clearable='clearable'
|
||||
@clear='clearIcon'
|
||||
@click='openDialog'
|
||||
>
|
||||
<template #append>
|
||||
<el-button :icon='customIcons[iconValue]' />
|
||||
</template>
|
||||
</el-input>
|
||||
<el-dialog v-model='dialogVisible' :title='placeholder' top='50px' width='66%'>
|
||||
<el-input v-model='inputValue' placeholder='搜索图标' size='large' :prefix-icon='Icons.Search' />
|
||||
<el-scrollbar v-if='Object.keys(iconsList).length'>
|
||||
<div class='icon-list'>
|
||||
<div v-for='item in iconsList' :key='item' class='icon-item' @click='selectIcon(item)'>
|
||||
<component :is='item'></component>
|
||||
<span>{{ item.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
<el-empty v-else description='未搜索到您要找的图标~' />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang='ts' setup name='SelectIcon'>
|
||||
import * as Icons from '@element-plus/icons-vue'
|
||||
|
||||
interface SelectIconProps {
|
||||
iconValue: string;
|
||||
title?: string;
|
||||
clearable?: boolean;
|
||||
placeholder?: string;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<SelectIconProps>(), {
|
||||
iconValue: '',
|
||||
title: '请选择图标',
|
||||
clearable: true,
|
||||
placeholder: '请选择图标',
|
||||
})
|
||||
|
||||
// 重新接收一下,防止打包后 clearable 报错
|
||||
const valueIcon = ref(props.iconValue)
|
||||
|
||||
// open Dialog
|
||||
const dialogVisible = ref(false)
|
||||
const openDialog = () => (dialogVisible.value = true)
|
||||
|
||||
// 选择图标(触发更新父组件数据)
|
||||
const emit = defineEmits<{
|
||||
'update:iconValue': [value: string];
|
||||
}>()
|
||||
const selectIcon = (item: any) => {
|
||||
dialogVisible.value = false
|
||||
valueIcon.value = item.name
|
||||
emit('update:iconValue', item.name)
|
||||
setTimeout(() => inputRef.value.blur(), 0)
|
||||
}
|
||||
|
||||
// 清空图标
|
||||
const inputRef = ref()
|
||||
const clearIcon = () => {
|
||||
valueIcon.value = ''
|
||||
emit('update:iconValue', '')
|
||||
setTimeout(() => inputRef.value.blur(), 0)
|
||||
}
|
||||
|
||||
// 监听搜索框值
|
||||
const inputValue = ref('')
|
||||
const customIcons: { [key: string]: any } = Icons
|
||||
const iconsList = computed((): { [key: string]: any } => {
|
||||
if (!inputValue.value) return Icons
|
||||
let result: { [key: string]: any } = {}
|
||||
for (const key in customIcons) {
|
||||
if (key.toLowerCase().indexOf(inputValue.value.toLowerCase()) > -1) result[key] = customIcons[key]
|
||||
}
|
||||
return result
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
@import "./index.scss";
|
||||
</style>
|
||||
Reference in New Issue
Block a user