feat: 图标选择器
This commit is contained in:
parent
2a9591320f
commit
9e90d3d410
33
src/components.d.ts
vendored
33
src/components.d.ts
vendored
@ -5,22 +5,23 @@
|
|||||||
// Read more: https://github.com/vuejs/core/pull/3399
|
// Read more: https://github.com/vuejs/core/pull/3399
|
||||||
export {}
|
export {}
|
||||||
|
|
||||||
declare module 'vue' {
|
declare module "vue" {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
BarcodeDraw: typeof import('./components/barcode-draw/index.vue')['default']
|
BarcodeDraw: (typeof import("./components/barcode-draw/index.vue"))["default"];
|
||||||
CodeView: typeof import('./components/code-view/index.vue')['default']
|
CodeView: (typeof import("./components/code-view/index.vue"))["default"];
|
||||||
ExternalLinkPage: typeof import('./components/external-link-page/index.vue')['default']
|
ExternalLinkPage: (typeof import("./components/external-link-page/index.vue"))["default"];
|
||||||
FillPage: typeof import('./components/fill-page/index.vue')['default']
|
FillPage: (typeof import("./components/fill-page/index.vue"))["default"];
|
||||||
InternalLinkPage: typeof import('./components/internal-link-page/index.vue')['default']
|
InternalLinkPage: (typeof import("./components/internal-link-page/index.vue"))["default"];
|
||||||
LangProvider: typeof import('./components/lang-provider/index.vue')['default']
|
LangProvider: (typeof import("./components/lang-provider/index.vue"))["default"];
|
||||||
MainTransition: typeof import('./components/main-transition/index.vue')['default']
|
MainTransition: (typeof import("./components/main-transition/index.vue"))["default"];
|
||||||
PinyinPro: typeof import('./components/pinyin-pro/index.vue')['default']
|
PinyinPro: (typeof import("./components/pinyin-pro/index.vue"))["default"];
|
||||||
QrcodeDraw: typeof import('./components/qrcode-draw/index.vue')['default']
|
QrcodeDraw: (typeof import("./components/qrcode-draw/index.vue"))["default"];
|
||||||
RouterLink: typeof import('vue-router')['RouterLink']
|
RouterLink: (typeof import("vue-router"))["RouterLink"];
|
||||||
RouterView: typeof import('vue-router')['RouterView']
|
RouterView: (typeof import("vue-router"))["RouterView"];
|
||||||
SelectIcon: typeof import('./components/select-icon/index.vue')['default']
|
SelectIcon: (typeof import("./components/select-icon/index.vue"))["default"];
|
||||||
SvgAndIcon: typeof import('./components/svg-and-icon/index.vue')['default']
|
SelectSvg: (typeof import("./components/select-svg/index.vue"))["default"];
|
||||||
SvgIcon: typeof import('./components/svg-icon/index.vue')['default']
|
SvgAndIcon: (typeof import("./components/svg-and-icon/index.vue"))["default"];
|
||||||
VerifyCode: typeof import('./components/verify-code/index.vue')['default']
|
SvgIcon: (typeof import("./components/svg-icon/index.vue"))["default"];
|
||||||
|
VerifyCode: (typeof import("./components/verify-code/index.vue"))["default"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-modal v-model:visible="visible" width="70vw" :top="'50px'" :align-center="false" :footer="false">
|
<div>
|
||||||
|
<a-input ref="inputRef" :style="{ width: '100%' }" placeholder="请选择图标" v-model="iconName" @focus="onFocus">
|
||||||
|
<template #suffix v-if="iconName">
|
||||||
|
<SvgIcon v-if="type == 'svg'" :name="iconName" :size="size" />
|
||||||
|
<component v-else :is="iconName" :size="size"></component>
|
||||||
|
</template>
|
||||||
|
<template #append>
|
||||||
|
<span class="icon-reset" @click="reset">重置</span>
|
||||||
|
</template>
|
||||||
|
</a-input>
|
||||||
|
<a-modal v-model:visible="visible" :unmount-on-close="true" width="70vw" :top="'50px'" :align-center="false" :footer="false">
|
||||||
<template #title> 请选择图标 </template>
|
<template #title> 请选择图标 </template>
|
||||||
<a-input
|
<a-input
|
||||||
:style="{
|
:style="{
|
||||||
@ -17,7 +27,8 @@
|
|||||||
<div class="over-scroll">
|
<div class="over-scroll">
|
||||||
<div class="icon-grid">
|
<div class="icon-grid">
|
||||||
<div v-for="item in iconList" :key="item" class="grid-item" @click="onIcon(item)">
|
<div v-for="item in iconList" :key="item" class="grid-item" @click="onIcon(item)">
|
||||||
<component :is="item" :size="30"></component>
|
<SvgIcon v-if="type == 'svg'" :name="item" :size="25" />
|
||||||
|
<component v-else :is="item" :size="25"></component>
|
||||||
<span>{{ item }}</span>
|
<span>{{ item }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -31,19 +42,55 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import * as ArcoIcons from "@arco-design/web-vue/es/icon";
|
import * as ArcoIcons from "@arco-design/web-vue/es/icon";
|
||||||
const emit = defineEmits(["select"]);
|
interface Props {
|
||||||
|
type?: string;
|
||||||
|
size?: number;
|
||||||
|
}
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
type: "arco", // 图标库类型,arco 或 svg
|
||||||
|
size: 25 // 图标大小-默认25px
|
||||||
|
});
|
||||||
|
|
||||||
|
const { type, size } = toRefs(props);
|
||||||
|
|
||||||
|
const emit = defineEmits(["update:modelValue"]);
|
||||||
|
|
||||||
|
const visible = ref<boolean>(false);
|
||||||
|
const iconName = ref<string>("");
|
||||||
|
|
||||||
|
const reset = () => {
|
||||||
|
iconName.value = "";
|
||||||
|
emit("update:modelValue", "");
|
||||||
|
};
|
||||||
|
|
||||||
|
const onFocus = () => {
|
||||||
|
searchName.value = "";
|
||||||
|
visible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// svg模块-assets/svgs文件夹下的所有svg图标
|
||||||
|
const SvgIconModules = import.meta.glob("@assets/svgs/*.svg");
|
||||||
|
// 搜索关键字
|
||||||
const searchName = ref<string>("");
|
const searchName = ref<string>("");
|
||||||
|
// icon列表
|
||||||
const iconList = computed(() => {
|
const iconList = computed(() => {
|
||||||
if (!ArcoIcons) return [];
|
|
||||||
let icons: string[] = [];
|
let icons: string[] = [];
|
||||||
|
if (type.value === "arco") {
|
||||||
|
if (!ArcoIcons) return [];
|
||||||
for (let key in ArcoIcons) {
|
for (let key in ArcoIcons) {
|
||||||
if (key != "default") icons.push(key);
|
if (key != "default") icons.push(key);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (!SvgIconModules) return [];
|
||||||
|
for (let path in SvgIconModules) {
|
||||||
|
icons.push(path.replace("/src/assets/svgs/", "").split(".svg")[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
// 若按照关键字搜索,则返回搜索结果
|
// 若按照关键字搜索,则返回搜索结果
|
||||||
if (searchName.value) {
|
if (searchName.value) {
|
||||||
return icons.filter(item => item.toLowerCase().includes(searchName.value.toLowerCase()));
|
return icons.filter(item => item.toLowerCase().includes(searchName.value.toLowerCase()));
|
||||||
@ -52,20 +99,12 @@ const iconList = computed(() => {
|
|||||||
return icons;
|
return icons;
|
||||||
});
|
});
|
||||||
|
|
||||||
const onIcon = (iconName: string) => {
|
// 选择图标
|
||||||
|
const onIcon = (name: string) => {
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
emit("select", iconName);
|
iconName.value = name;
|
||||||
|
emit("update:modelValue", name);
|
||||||
};
|
};
|
||||||
|
|
||||||
const visible = ref<boolean>(false);
|
|
||||||
const open = () => {
|
|
||||||
searchName.value = "";
|
|
||||||
visible.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
defineExpose({
|
|
||||||
open
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -98,4 +137,7 @@ defineExpose({
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 300px;
|
height: 300px;
|
||||||
}
|
}
|
||||||
|
.icon-reset {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,51 +1,35 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="snow-page">
|
<div class="snow-page">
|
||||||
<div class="snow-inner">
|
<div class="snow-inner">
|
||||||
<div class="title">图标选择器</div>
|
<a-row class="grid-demo" :gutter="24">
|
||||||
<a-input ref="inputRef" :style="{ width: '400px' }" placeholder="请选择图标" v-model="iconName" @focus="onFocus">
|
<a-col :span="12">
|
||||||
<template #suffix v-if="iconName">
|
<a-card title="图标选择器" :style="{ width: '100%' }">
|
||||||
<component :is="iconName"></component>
|
<SelectIcon type="arco" v-model="iconName" />
|
||||||
</template>
|
|
||||||
<template #append>
|
|
||||||
<span class="icon-reset" @click="reset">重置</span>
|
|
||||||
</template>
|
|
||||||
</a-input>
|
|
||||||
<a-divider />
|
|
||||||
<div class="target-title">当前选择的图标:</div>
|
<div class="target-title">当前选择的图标:</div>
|
||||||
<component v-if="iconName" :is="iconName" size="50"></component>
|
<component v-if="iconName" :is="iconName" :size="50"></component>
|
||||||
<a-empty v-else />
|
<a-empty v-else />
|
||||||
<SelectIcon ref="SelectIconRef" @select="select" />
|
</a-card>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-card title="SVG选择器" :style="{ width: '100%' }">
|
||||||
|
<SelectIcon type="svg" v-model="svgName" />
|
||||||
|
<div class="target-title">当前选择的图标:</div>
|
||||||
|
<SvgIcon v-if="svgName" :name="svgName" :size="50" />
|
||||||
|
<a-empty v-else />
|
||||||
|
</a-card>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const iconName = ref<string>("");
|
const iconName = ref<string>("");
|
||||||
const SelectIconRef = ref();
|
const svgName = ref<string>("");
|
||||||
|
|
||||||
const onFocus = () => {
|
|
||||||
SelectIconRef.value.open();
|
|
||||||
};
|
|
||||||
|
|
||||||
const reset = () => {
|
|
||||||
iconName.value = "";
|
|
||||||
};
|
|
||||||
|
|
||||||
const select = (icon: string) => {
|
|
||||||
iconName.value = icon;
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.title {
|
|
||||||
margin-bottom: $margin;
|
|
||||||
font-size: $font-size-title-1;
|
|
||||||
color: $color-text-1;
|
|
||||||
}
|
|
||||||
.target-title {
|
.target-title {
|
||||||
margin-bottom: $margin;
|
margin: $margin 0;
|
||||||
}
|
|
||||||
.icon-reset {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user