图标工具

This commit is contained in:
Gary Fu
2023-12-24 17:50:48 +08:00
parent 9b777948c9
commit dbc284bf8b
8 changed files with 148 additions and 15 deletions

View File

@@ -35,6 +35,19 @@ html, body, #app, .index-container {
.padding-right2 { .padding-right2 {
padding-right: 10px; padding-right: 10px;
} }
.padding-top1 {
padding-top: 5px;
}
.padding-top2 {
padding-top: 10px;
}
.padding-bottom1 {
padding-bottom: 5px;
}
.padding-bottom2 {
padding-bottom: 10px;
}
.text-center { .text-center {
text-align: center; text-align: center;
} }

View File

@@ -1,19 +1,29 @@
<script setup> <script setup>
defineProps({ import { computed } from 'vue'
import { ICON_PREFIX } from '@/icons'
import kebabCase from 'lodash/kebabCase'
const props = defineProps({
icon: { icon: {
type: String, type: String,
required: false required: false
} }
}) })
const calcIcon = computed(() => {
if (props.icon) {
return `${ICON_PREFIX}${kebabCase(props.icon)}`
}
return props.icon
})
</script> </script>
<template> <template>
<el-icon <el-icon
v-if="icon" v-if="calcIcon"
v-bind="$attrs" v-bind="$attrs"
> >
<component <component
:is="icon" :is="calcIcon"
/> />
</el-icon> </el-icon>
</template> </template>

View File

@@ -1,12 +1,37 @@
import * as ElementPlusIconsVue from '@element-plus/icons-vue' import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import * as MaterialIconsVue from '@vicons/material' import * as MaterialIconsVue from '@vicons/material'
import kebabCase from 'lodash/kebabCase'
export const INSTALL_ICONS = []
export const ICON_PREFIX = 'icon-'
/**
* icon组件注册工具,默认增加icon-前缀,如果重复,再增加前缀
* @param app {import('vue').App} Vue实例
* @param key {string}图标名称
* @param component {import('vue').Component}组件
* @param prefix 如果已经注册,增加前缀防止覆盖
*/
const registryIconComponent = (app, key, component, prefix) => {
let componentName = `${ICON_PREFIX}${kebabCase(key)}` // 组件名字
if (app.component(componentName)) {
key = `${prefix}${key}`
componentName = `${ICON_PREFIX}${kebabCase(key)}`
}
INSTALL_ICONS.push(key)
app.component(componentName, component)
}
export default { export default {
/**
* 注册图标
* @param app {import('vue').App}
*/
install (app) { install (app) {
for (const [key, component] of Object.entries(ElementPlusIconsVue)) { for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component) registryIconComponent(app, key, component, 'El')
} }
for (const [key, component] of Object.entries(MaterialIconsVue)) { for (const [key, component] of Object.entries(MaterialIconsVue)) {
app.component(key, component) registryIconComponent(app, key, component, 'Md')
} }
} }
} }

View File

@@ -6,6 +6,8 @@ menu.label.userManagement = '用户管理'
menu.label.roleManagement = '角色管理' menu.label.roleManagement = '角色管理'
menu.label.authorityManagement = '权限管理' menu.label.authorityManagement = '权限管理'
menu.label.menuManagement = '菜单管理' menu.label.menuManagement = '菜单管理'
menu.label.toolsManagement = '工具管理'
menu.label.toolsIcons = '图标管理'
menu.label.errorPage = '错误页面' menu.label.errorPage = '错误页面'
menu.label.errorPage404 = '找不到页面' menu.label.errorPage404 = '找不到页面'
menu.label.errorPage403 = '没有权限' menu.label.errorPage403 = '没有权限'

View File

@@ -6,6 +6,8 @@ menu.label.userManagement = 'User Management'
menu.label.roleManagement = 'Role Management' menu.label.roleManagement = 'Role Management'
menu.label.authorityManagement = 'Authority Management' menu.label.authorityManagement = 'Authority Management'
menu.label.menuManagement = 'Menu Management' menu.label.menuManagement = 'Menu Management'
menu.label.toolsManagement = 'Tools'
menu.label.toolsIcons = 'Icons'
menu.label.errorPage = 'Error Page' menu.label.errorPage = 'Error Page'
menu.label.errorPage404 = 'Not Found' menu.label.errorPage404 = 'Not Found'
menu.label.errorPage403 = 'Access Denied' menu.label.errorPage403 = 'Access Denied'

View File

@@ -17,6 +17,10 @@ const router = createRouter({
path: 'personal', path: 'personal',
name: 'personal', name: 'personal',
component: () => import('@/views/account/PersonalInfo.vue') component: () => import('@/views/account/PersonalInfo.vue')
}, {
path: 'icons',
name: 'icons',
component: () => import('@/views/Icons.vue')
}, },
{ {
path: '/:pathMatch(.*)*', path: '/:pathMatch(.*)*',

View File

@@ -38,7 +38,7 @@ export const useBaseTopMenus = () => {
click: () => globalConfigStore.changeTheme(!globalConfigStore.isDarkTheme) click: () => globalConfigStore.changeTheme(!globalConfigStore.isDarkTheme)
}, },
{ {
icon: 'DisplaySettingsRound', icon: 'AutoAwesomeMosaicFilled',
index: 'layout', index: 'layout',
isDropdown: true, isDropdown: true,
children: [ children: [
@@ -109,21 +109,18 @@ export const useBusinessMenus = () => {
] ]
}, },
{ {
icon: 'WarningFilled', icon: 'BuildRound',
labelKey: 'menu.label.errorPage', labelKey: 'menu.label.toolsManagement',
children: [ children: [
{ {
index: '/not-found', index: '/not-found',
icon: 'Warning', icon: 'WarningFilled',
labelKey: 'menu.label.errorPage404' labelKey: 'menu.label.errorPage404'
}, },
{ {
icon: 'Warning', index: '/icons',
labelKey: 'menu.label.errorPage403' icon: 'InsertEmoticonOutlined',
}, labelKey: 'menu.label.toolsIcons'
{
icon: 'Warning',
labelKey: 'menu.label.errorPage500'
} }
] ]
}]) }])

80
src/views/Icons.vue Normal file
View File

@@ -0,0 +1,80 @@
<script setup>
import { INSTALL_ICONS } from '@/icons'
import chunk from 'lodash/chunk'
import { computed, ref } from 'vue'
import { useClipboard } from '@vueuse/core'
import { ElMessage } from 'element-plus'
const colSize = ref(8)
const showSize = ref(200)
const keyWords = ref('')
const filterIcons = computed(() => {
let icons = INSTALL_ICONS
if (keyWords.value) {
icons = icons.filter(icon => icon.toLowerCase().includes(keyWords.value.toLowerCase()))
}
return chunk(icons.slice(0, showSize.value), colSize.value)
})
const copyIcon = (icon) => {
const { copy, isSupported } = useClipboard()
if (isSupported) {
copy(icon)
ElMessage({
message: `Copied: ${icon}`,
type: 'success'
})
} else {
ElMessage({
message: `Copy Not supported: ${icon}`,
type: 'error'
})
}
}
</script>
<template>
<div>
<el-row>
<el-col>
<el-form label-width="120px">
<el-form-item label="图标名字">
<el-input
v-model="keyWords"
:placeholder="`输入关键字搜索图标,只显示前${showSize}个图标`"
/>
</el-form-item>
</el-form>
</el-col>
</el-row>
<el-row
v-for="(icons, chunkIdx) in filterIcons"
:key="chunkIdx"
>
<el-col
v-for="icon in icons"
:key="icon"
:span="24/colSize"
class="text-center"
>
<a
class="el-button el-button--large is-text"
style="height:80px;"
@click="copyIcon(icon)"
>
<div>
<common-icon
size="20"
:icon="icon"
/>
</div>
</a>
</el-col>
</el-row>
</div>
</template>
<style scoped>
</style>