element-plus图标选择器封装,vue3动态路由菜单

效果图如下,(下篇文章为:vue3动态路由如何实现,addRoutes失效?)
1.下载图标
# 选择一个你喜欢的包管理器

# NPM
$ npm install @element-plus/icons-vue
# Yarn
$ yarn add @element-plus/icons-vue
# pnpm
$ pnpm install @element-plus/icons-vue
2.引入到vue3项目
import { createApp } from "vue";
import App from "@/App.vue";

import ElementPlus from "element-plus";
import "element-plus/dist/index.css";
import * as ElementPlusIconsVue from "@element-plus/icons-vue";


const app = createApp(App);
app.config.globalProperties.$icons = [];

for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
  app.config.globalProperties.$icons.push(key);
  app.component(key, component);
}
app.use(ElementPlus).mount("#app");
3. 封装图标选择器组件
<script setup lang="ts">
import {
  ComponentInternalInstance,
  defineEmits,
  defineProps,
  getCurrentInstance,
} from "vue";

const {
  appContext: {
    app: {
      config: { globalProperties },
    },
  },
} = getCurrentInstance() as ComponentInternalInstance;

interface Props {
  modelValue: string;
}
const props = defineProps<Props>();

const emits = defineEmits(["update:modelValue"]);
/**清空选中的图标 */
function closeIcon() {
  emits("update:modelValue", "");
}
</script>

<template>
  <el-popover trigger="click" :width="500">
    <template #reference>
      <el-button class="click-button" :icon="props.modelValue">
        {{ props.modelValue }}
        <p v-if="!modelValue" class="button-placeholder">点击选择图标</p>
        <el-icon @click.stop="closeIcon" v-if="modelValue" class="close-icon"
          ><CircleClose
        /></el-icon>
      </el-button>
    </template>
    <div class="el-icon-picker">
      <component
        v-for="icon in globalProperties.$icons"
        :key="icon"
        :class="[icon, 'icon', { 'icon-active': icon == props.modelValue }]"
        :is="icon"
        @click="emits('update:modelValue', icon)"
      >
      </component>
    </div>
  </el-popover>
</template>

<style scoped lang="scss">
.el-icon-picker {
  height: 256px;
  overflow-y: scroll;
  display: flex;
  flex-wrap: wrap;
}

.icon {
  display: inline-block;
  width: 24px;
  height: 24px;
  color: var(--el-text-color-regular);
  font-size: 20px;
  border-radius: 4px;
  cursor: pointer;
  text-align: center;
  line-height: 45px;
  margin: 5px;
}

.icon:hover {
  color: var(--el-color-primary);
}

.icon-active {
  color: var(--el-color-primary);
}
.click-button {
  width: 100%;
  position: relative;
}
::v-deep .el-button {
  justify-content: flex-start !important;
}
.button-placeholder {
  position: absolute;
  display: block;
  left: 10px;
  top: 50%;
  transform: translateY(-50%);
  color: #a8abc3;
}
.close-icon {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
}
.el-button:focus,
.el-button:hover {
  background: #fff;
}
</style>
4.父组件使用方式:
<script setup lang="ts">
import iconSon from "./iconSon.vue";
</script>

<template>
       <iconSon v-model="ruleForm.icon"></iconSon>
</template>
5.得到图标值,如何渲染
        //如果渲染到列表,那么要进行判断,因为有可能没值,就报错了
        <el-icon>
          <component v-if="data" :class="[data]" :is="data"> </component>
        </el-icon>
6.下篇文章为:vue3动态路由如何实现,addRoutes失效?

vue3动态路由如何实现?点击下方链接到下篇文章(超细)

vue3动态路由到底如何实现vue-router4中addRoutes失效?-CSDN博客