From 8b7c2fe49917d670eb2a03cecda23ea50961c494 Mon Sep 17 00:00:00 2001
From: Your Name <123456>
Date: 星期二, 09 八月 2022 09:26:29 +0800
Subject: [PATCH] lct

---
 src/components/iconSelector/index.vue |  477 ++++++++++++++++++++++++++++-------------------------------
 1 files changed, 228 insertions(+), 249 deletions(-)

diff --git a/src/components/iconSelector/index.vue b/src/components/iconSelector/index.vue
index 3010e16..f4547d9 100644
--- a/src/components/iconSelector/index.vue
+++ b/src/components/iconSelector/index.vue
@@ -1,252 +1,231 @@
-<!--<template>-->
-<!--	<div class="icon-selector w100 h100">-->
-<!--		<el-popover-->
-<!--			placement="bottom"-->
-<!--			:width="fontIconWidth"-->
-<!--			trigger="click"-->
-<!--			transition="el-zoom-in-top"-->
-<!--			popper-class="icon-selector-popper"-->
-<!--			@show="onPopoverShow"-->
-<!--		>-->
-<!--			<template #reference>-->
-<!--				<el-input-->
-<!--					v-model="fontIconSearch"-->
-<!--					:placeholder="fontIconPlaceholder"-->
-<!--					:clearable="clearable"-->
-<!--					:disabled="disabled"-->
-<!--					:size="size"-->
-<!--					ref="inputWidthRef"-->
-<!--					@clear="onClearFontIcon"-->
-<!--					@focus="onIconFocus"-->
-<!--					@blur="onIconBlur"-->
-<!--				>-->
-<!--					<template #prepend>-->
-<!--						<SvgIcon-->
-<!--							:name="fontIconPrefix === '' ? prepend : fontIconPrefix"-->
-<!--							class="font14"-->
-<!--							v-if="fontIconPrefix === '' ? prepend?.indexOf('ele-') > -1 : fontIconPrefix?.indexOf('ele-') > -1"-->
-<!--						/>-->
-<!--						<i v-else :class="fontIconPrefix === '' ? prepend : fontIconPrefix" class="font14"></i>-->
-<!--					</template>-->
-<!--				</el-input>-->
-<!--			</template>-->
-<!--			<template #default>-->
-<!--				<div class="icon-selector-warp">-->
-<!--					<div class="icon-selector-warp-title flex">-->
-<!--						<div class="flex-auto">{{ title }}</div>-->
-<!--						<div class="icon-selector-warp-title-tab" v-if="type === 'all'">-->
-<!--							<span :class="{ 'span-active': fontIconType === 'ali' }" @click="onIconChange('ali')" class="ml10" title="iconfont 图标">ali</span>-->
-<!--							<span :class="{ 'span-active': fontIconType === 'ele' }" @click="onIconChange('ele')" class="ml10" title="elementPlus 图标">ele</span>-->
-<!--							<span :class="{ 'span-active': fontIconType === 'awe' }" @click="onIconChange('awe')" class="ml10" title="fontawesome 图标">awe</span>-->
-<!--						</div>-->
-<!--					</div>-->
-<!--					<div class="icon-selector-warp-row">-->
-<!--						<el-scrollbar ref="selectorScrollbarRef">-->
-<!--							<el-row :gutter="10" v-if="fontIconSheetsFilterList.length > 0">-->
-<!--								<el-col :xs="6" :sm="4" :md="4" :lg="4" :xl="4" @click="onColClick(v)" v-for="(v, k) in fontIconSheetsFilterList" :key="k">-->
-<!--									<div class="icon-selector-warp-item" :class="{ 'icon-selector-active': fontIconPrefix === v }">-->
-<!--										<div class="flex-margin">-->
-<!--											<div class="icon-selector-warp-item-value">-->
-<!--												<SvgIcon :name="v" />-->
-<!--											</div>-->
-<!--										</div>-->
-<!--									</div>-->
-<!--								</el-col>-->
-<!--							</el-row>-->
-<!--							<el-empty :image-size="100" v-if="fontIconSheetsFilterList.length <= 0" :description="emptyDescription"></el-empty>-->
-<!--						</el-scrollbar>-->
-<!--					</div>-->
-<!--				</div>-->
-<!--			</template>-->
-<!--		</el-popover>-->
-<!--	</div>-->
-<!--</template>-->
+<template>
+    <div class="icon-selector w100 h100">
+        <el-popover placement="bottom" :width="fontIconWidth" trigger="click" transition="el-zoom-in-top" popper-class="icon-selector-popper" @show="onPopoverShow">
+            <template #reference>
+                <el-input v-model="fontIconSearch" :placeholder="fontIconPlaceholder" :clearable="clearable" :disabled="disabled" :size="size" ref="inputWidthRef" @clear="onClearFontIcon" @focus="onIconFocus" @blur="onIconBlur">
+                    <template #prepend>
+                        <SvgIcon :name="fontIconPrefix === '' ? prepend : fontIconPrefix" class="font14" v-if="fontIconPrefix === '' ? prepend?.indexOf('ele-') > -1 : fontIconPrefix?.indexOf('ele-') > -1" />
+                        <i v-else :class="fontIconPrefix === '' ? prepend : fontIconPrefix" class="font14"></i>
+                    </template>
+                </el-input>
+            </template>
+            <template #default>
+                <div class="icon-selector-warp">
+                    <div class="icon-selector-warp-title flex">
+                        <div class="flex-auto">{{ title }}</div>
+                        <div class="icon-selector-warp-title-tab" v-if="type === 'all'">
+                            <span :class="{ 'span-active': fontIconType === 'ali' }" @click="onIconChange('ali')" class="ml10" title="iconfont 图标">ali</span>
+                            <span :class="{ 'span-active': fontIconType === 'ele' }" @click="onIconChange('ele')" class="ml10" title="elementPlus 图标">ele</span>
+                            <span :class="{ 'span-active': fontIconType === 'awe' }" @click="onIconChange('awe')" class="ml10" title="fontawesome 图标">awe</span>
+                        </div>
+                    </div>
+                    <div class="icon-selector-warp-row">
+                        <el-scrollbar ref="selectorScrollbarRef">
+                            <el-row :gutter="10" v-if="fontIconSheetsFilterList.length > 0">
+                                <el-col :xs="6" :sm="4" :md="4" :lg="4" :xl="4" @click="onColClick(v)" v-for="(v, k) in fontIconSheetsFilterList" :key="k">
+                                    <div class="icon-selector-warp-item" :class="{ 'icon-selector-active': fontIconPrefix === v }">
+                                        <div class="flex-margin">
+                                            <div class="icon-selector-warp-item-value">
+                                                <SvgIcon :name="v" />
+                                            </div>
+                                        </div>
+                                    </div>
+                                </el-col>
+                            </el-row>
+                            <el-empty :image-size="100" v-if="fontIconSheetsFilterList.length <= 0" :description="emptyDescription"></el-empty>
+                        </el-scrollbar>
+                    </div>
+                </div>
+            </template>
+        </el-popover>
+    </div>
+</template>
 
-<!--<script lang="ts">-->
-<!--import { ref, toRefs, reactive, onMounted, nextTick, computed, watch, defineComponent } from 'vue';-->
-<!--import initIconfont from '/@/utils/getStyleSheets';-->
+<script lang="ts">
+import { ref, toRefs, reactive, onMounted, nextTick, computed, watch, defineComponent } from 'vue';
+// import initIconfont from '/@/utils/getStyleSheets';
 
-<!--export default defineComponent({-->
-<!--	name: 'iconSelector',-->
-<!--	emits: ['update:modelValue', 'get', 'clear'],-->
-<!--	props: {-->
-<!--		// 输入框前置内容-->
-<!--		prepend: {-->
-<!--			type: String,-->
-<!--			default: () => 'ele-Pointer',-->
-<!--		},-->
-<!--		// 输入框占位文本-->
-<!--		placeholder: {-->
-<!--			type: String,-->
-<!--			default: () => '请输入内容搜索图标或者选择图标',-->
-<!--		},-->
-<!--		// 输入框占位文本-->
-<!--		size: {-->
-<!--			type: String,-->
-<!--			default: () => 'default',-->
-<!--		},-->
-<!--		// 弹窗标题-->
-<!--		title: {-->
-<!--			type: String,-->
-<!--			default: () => '请选择图标',-->
-<!--		},-->
-<!--		// icon 图标类型-->
-<!--		type: {-->
-<!--			type: String,-->
-<!--			default: () => 'ele',-->
-<!--		},-->
-<!--		// 禁用-->
-<!--		disabled: {-->
-<!--			type: Boolean,-->
-<!--			default: () => false,-->
-<!--		},-->
-<!--		// 是否可清空-->
-<!--		clearable: {-->
-<!--			type: Boolean,-->
-<!--			default: () => true,-->
-<!--		},-->
-<!--		// 自定义空状态描述文字-->
-<!--		emptyDescription: {-->
-<!--			type: String,-->
-<!--			default: () => '无相关图标',-->
-<!--		},-->
-<!--		// 双向绑定值,默认为 modelValue,-->
-<!--		// 参考:https://v3.cn.vuejs.org/guide/migration/v-model.html#%E8%BF%81%E7%A7%BB%E7%AD%96%E7%95%A5-->
-<!--		// 参考:https://v3.cn.vuejs.org/guide/component-custom-events.html#%E5%A4%9A%E4%B8%AA-v-model-%E7%BB%91%E5%AE%9A-->
-<!--		modelValue: String,-->
-<!--	},-->
-<!--	setup(props, { emit }) {-->
-<!--		const inputWidthRef = ref();-->
-<!--		const selectorScrollbarRef = ref();-->
-<!--		const state = reactive({-->
-<!--			fontIconPrefix: '',-->
-<!--			fontIconWidth: 0,-->
-<!--			fontIconSearch: '',-->
-<!--			fontIconTabsIndex: 0,-->
-<!--			fontIconSheetsList: [],-->
-<!--			fontIconPlaceholder: '',-->
-<!--			fontIconType: 'ali',-->
-<!--			fontIconShow: true,-->
-<!--		});-->
-<!--		// 处理 input 获取焦点时,modelValue 有值时,改变 input 的 placeholder 值-->
-<!--		const onIconFocus = () => {-->
-<!--			if (!props.modelValue) return false;-->
-<!--			state.fontIconSearch = '';-->
-<!--			state.fontIconPlaceholder = props.modelValue;-->
-<!--		};-->
-<!--		// 处理 input 失去焦点时,为空将清空 input 值,为点击选中图标时,将取原先值-->
-<!--		const onIconBlur = () => {-->
-<!--			setTimeout(() => {-->
-<!--				const icon = state.fontIconSheetsList.filter((icon: string) => icon === state.fontIconSearch);-->
-<!--				if (icon.length <= 0) state.fontIconSearch = '';-->
-<!--			}, 300);-->
-<!--		};-->
-<!--		// 处理 icon 双向绑定数值回显-->
-<!--		const initModeValueEcho = () => {-->
-<!--			if (props.modelValue === '') return ((<string | undefined>state.fontIconPlaceholder) = props.placeholder);-->
-<!--			(<string | undefined>state.fontIconPlaceholder) = props.modelValue;-->
-<!--			(<string | undefined>state.fontIconPrefix) = props.modelValue;-->
-<!--		};-->
-<!--		// 处理 icon type 类型为 all 时,类型 ali、ele、awe 回显问题-->
-<!--		const initFontIconTypeEcho = () => {-->
-<!--			if ((<any>props.modelValue)?.indexOf('iconfont') > -1) onIconChange('ali');-->
-<!--			else if ((<any>props.modelValue)?.indexOf('ele-') > -1) onIconChange('ele');-->
-<!--			else if ((<any>props.modelValue)?.indexOf('fa') > -1) onIconChange('awe');-->
-<!--			else onIconChange('ali');-->
-<!--		};-->
-<!--		// 图标搜索及图标数据显示-->
-<!--		const fontIconSheetsFilterList = computed(() => {-->
-<!--			if (!state.fontIconSearch) return state.fontIconSheetsList;-->
-<!--			let search = state.fontIconSearch.trim().toLowerCase();-->
-<!--			return state.fontIconSheetsList.filter((item: any) => {-->
-<!--				if (item.toLowerCase().indexOf(search) !== -1) return item;-->
-<!--			});-->
-<!--		});-->
-<!--		// 获取 input 的宽度-->
-<!--		const getInputWidth = () => {-->
-<!--			nextTick(() => {-->
-<!--				state.fontIconWidth = inputWidthRef.value.$el.offsetWidth;-->
-<!--			});-->
-<!--		};-->
-<!--		// 监听页面宽度改变-->
-<!--		const initResize = () => {-->
-<!--			window.addEventListener('resize', () => {-->
-<!--				getInputWidth();-->
-<!--			});-->
-<!--		};-->
-<!--		// 初始化数据-->
-<!--		const initFontIconData = async (type: string) => {-->
-<!--			state.fontIconSheetsList = [];-->
-<!--			if (type === 'ali') {-->
-<!--				await initIconfont.ali().then((res: any) => {-->
-<!--					// 阿里字体图标使用 `iconfont xxx`-->
-<!--					state.fontIconSheetsList = res.map((i: string) => `iconfont ${i}`);-->
-<!--				});-->
-<!--			} else if (type === 'ele') {-->
-<!--				await initIconfont.ele().then((res: any) => {-->
-<!--					state.fontIconSheetsList = res;-->
-<!--				});-->
-<!--			} else if (type === 'awe') {-->
-<!--				await initIconfont.awe().then((res: any) => {-->
-<!--					// fontawesome字体图标使用 `fa xxx`-->
-<!--					state.fontIconSheetsList = res.map((i: string) => `fa ${i}`);-->
-<!--				});-->
-<!--			}-->
-<!--			// 初始化 input 的 placeholder-->
-<!--			// 参考(单项数据流):https://cn.vuejs.org/v2/guide/components-props.html?#%E5%8D%95%E5%90%91%E6%95%B0%E6%8D%AE%E6%B5%81-->
-<!--			state.fontIconPlaceholder = props.placeholder;-->
-<!--			// 初始化双向绑定回显-->
-<!--			initModeValueEcho();-->
-<!--		};-->
-<!--		// 图标点击切换-->
-<!--		const onIconChange = (type: string) => {-->
-<!--			state.fontIconType = type;-->
-<!--			initFontIconData(type);-->
-<!--		};-->
-<!--		// 获取当前点击的 icon 图标-->
-<!--		const onColClick = (v: any) => {-->
-<!--			state.fontIconPlaceholder = v;-->
-<!--			state.fontIconPrefix = v;-->
-<!--			emit('get', state.fontIconPrefix);-->
-<!--			emit('update:modelValue', state.fontIconPrefix);-->
-<!--		};-->
-<!--		// 清空当前点击的 icon 图标-->
-<!--		const onClearFontIcon = () => {-->
-<!--			state.fontIconPrefix = '';-->
-<!--			emit('clear', state.fontIconPrefix);-->
-<!--			emit('update:modelValue', state.fontIconPrefix);-->
-<!--		};-->
-<!--		// 监听 Popover 打开,用于双向绑定值回显-->
-<!--		const onPopoverShow = () => {-->
-<!--			initModeValueEcho();-->
-<!--			initFontIconTypeEcho();-->
-<!--		};-->
-<!--		// 页面加载时-->
-<!--		onMounted(() => {-->
-<!--			initModeValueEcho();-->
-<!--			initResize();-->
-<!--			getInputWidth();-->
-<!--		});-->
+export default defineComponent({
+    name: 'iconSelector',
+    emits: ['update:modelValue', 'get', 'clear'],
+    props: {
+        // 输入框前置内容
+        prepend: {
+            type: String,
+            default: () => 'ele-Pointer'
+        },
+        // 输入框占位文本
+        placeholder: {
+            type: String,
+            default: () => '请输入内容搜索图标或者选择图标'
+        },
+        // 输入框占位文本
+        size: {
+            type: String,
+            default: () => 'default'
+        },
+        // 弹窗标题
+        title: {
+            type: String,
+            default: () => '请选择图标'
+        },
+        // icon 图标类型
+        type: {
+            type: String,
+            default: () => 'ele'
+        },
+        // 禁用
+        disabled: {
+            type: Boolean,
+            default: () => false
+        },
+        // 是否可清空
+        clearable: {
+            type: Boolean,
+            default: () => true
+        },
+        // 自定义空状态描述文字
+        emptyDescription: {
+            type: String,
+            default: () => '无相关图标'
+        },
+        // 双向绑定值,默认为 modelValue,
+        // 参考:https://v3.cn.vuejs.org/guide/migration/v-model.html#%E8%BF%81%E7%A7%BB%E7%AD%96%E7%95%A5
+        // 参考:https://v3.cn.vuejs.org/guide/component-custom-events.html#%E5%A4%9A%E4%B8%AA-v-model-%E7%BB%91%E5%AE%9A
+        modelValue: String
+    },
+    setup(props, { emit }) {
+        const inputWidthRef = ref();
+        const selectorScrollbarRef = ref();
+        const state = reactive({
+            fontIconPrefix: '',
+            fontIconWidth: 0,
+            fontIconSearch: '',
+            fontIconTabsIndex: 0,
+            fontIconSheetsList: [],
+            fontIconPlaceholder: '',
+            fontIconType: 'ali',
+            fontIconShow: true
+        });
+        // 处理 input 获取焦点时,modelValue 有值时,改变 input 的 placeholder 值
+        const onIconFocus = () => {
+            if (!props.modelValue) return false;
+            state.fontIconSearch = '';
+            state.fontIconPlaceholder = props.modelValue;
+        };
+        // 处理 input 失去焦点时,为空将清空 input 值,为点击选中图标时,将取原先值
+        const onIconBlur = () => {
+            setTimeout(() => {
+                const icon = state.fontIconSheetsList.filter((icon: string) => icon === state.fontIconSearch);
+                if (icon.length <= 0) state.fontIconSearch = '';
+            }, 300);
+        };
+        // 处理 icon 双向绑定数值回显
+        const initModeValueEcho = () => {
+            if (props.modelValue === '') return ((<string | undefined>state.fontIconPlaceholder) = props.placeholder);
+            (<string | undefined>state.fontIconPlaceholder) = props.modelValue;
+            (<string | undefined>state.fontIconPrefix) = props.modelValue;
+        };
+        // 处理 icon type 类型为 all 时,类型 ali、ele、awe 回显问题
+        const initFontIconTypeEcho = () => {
+            if ((<any>props.modelValue)?.indexOf('iconfont') > -1) onIconChange('ali');
+            else if ((<any>props.modelValue)?.indexOf('ele-') > -1) onIconChange('ele');
+            else if ((<any>props.modelValue)?.indexOf('fa') > -1) onIconChange('awe');
+            else onIconChange('ali');
+        };
+        // 图标搜索及图标数据显示
+        const fontIconSheetsFilterList = computed(() => {
+            if (!state.fontIconSearch) return state.fontIconSheetsList;
+            let search = state.fontIconSearch.trim().toLowerCase();
+            return state.fontIconSheetsList.filter((item: any) => {
+                if (item.toLowerCase().indexOf(search) !== -1) return item;
+            });
+        });
+        // 获取 input 的宽度
+        const getInputWidth = () => {
+            nextTick(() => {
+                state.fontIconWidth = inputWidthRef.value.$el.offsetWidth;
+            });
+        };
+        // 监听页面宽度改变
+        const initResize = () => {
+            window.addEventListener('resize', () => {
+                getInputWidth();
+            });
+        };
+        // 初始化数据
+        const initFontIconData = async (type: string) => {
+            state.fontIconSheetsList = [];
+            if (type === 'ali') {
+                await initIconfont.ali().then((res: any) => {
+                    // 阿里字体图标使用 `iconfont xxx`
+                    state.fontIconSheetsList = res.map((i: string) => `iconfont ${i}`);
+                });
+            } else if (type === 'ele') {
+                await initIconfont.ele().then((res: any) => {
+                    state.fontIconSheetsList = res;
+                });
+            } else if (type === 'awe') {
+                await initIconfont.awe().then((res: any) => {
+                    // fontawesome字体图标使用 `fa xxx`
+                    state.fontIconSheetsList = res.map((i: string) => `fa ${i}`);
+                });
+            }
+            // 初始化 input 的 placeholder
+            // 参考(单项数据流):https://cn.vuejs.org/v2/guide/components-props.html?#%E5%8D%95%E5%90%91%E6%95%B0%E6%8D%AE%E6%B5%81
+            state.fontIconPlaceholder = props.placeholder;
+            // 初始化双向绑定回显
+            initModeValueEcho();
+        };
+        // 图标点击切换
+        const onIconChange = (type: string) => {
+            state.fontIconType = type;
+            initFontIconData(type);
+        };
+        // 获取当前点击的 icon 图标
+        const onColClick = (v: any) => {
+            state.fontIconPlaceholder = v;
+            state.fontIconPrefix = v;
+            emit('get', state.fontIconPrefix);
+            emit('update:modelValue', state.fontIconPrefix);
+        };
+        // 清空当前点击的 icon 图标
+        const onClearFontIcon = () => {
+            state.fontIconPrefix = '';
+            emit('clear', state.fontIconPrefix);
+            emit('update:modelValue', state.fontIconPrefix);
+        };
+        // 监听 Popover 打开,用于双向绑定值回显
+        const onPopoverShow = () => {
+            initModeValueEcho();
+            initFontIconTypeEcho();
+        };
+        // 页面加载时
+        onMounted(() => {
+            initModeValueEcho();
+            initResize();
+            getInputWidth();
+        });
 
-<!--		// 监听双向绑定 modelValue 的变化-->
-<!--		watch(-->
-<!--			() => props.modelValue,-->
-<!--			() => {-->
-<!--				initModeValueEcho();-->
-<!--			}-->
-<!--		);-->
-<!--		return {-->
-<!--			inputWidthRef,-->
-<!--			selectorScrollbarRef,-->
-<!--			fontIconSheetsFilterList,-->
-<!--			onColClick,-->
-<!--			onIconChange,-->
-<!--			onClearFontIcon,-->
-<!--			onIconFocus,-->
-<!--			onIconBlur,-->
-<!--			onPopoverShow,-->
-<!--			...toRefs(state),-->
-<!--		};-->
-<!--	},-->
-<!--});-->
-<!--</script>-->
+        // 监听双向绑定 modelValue 的变化
+        watch(
+            () => props.modelValue,
+            () => {
+                initModeValueEcho();
+            }
+        );
+        return {
+            inputWidthRef,
+            selectorScrollbarRef,
+            fontIconSheetsFilterList,
+            onColClick,
+            onIconChange,
+            onClearFontIcon,
+            onIconFocus,
+            onIconBlur,
+            onPopoverShow,
+            ...toRefs(state)
+        };
+    }
+});
+</script>

--
Gitblit v1.9.2