element-icon 引入

安装

解析3中,已经安装过

创建plugins 文件夹

有来团队后台项目-解析6-LMLPHP
icons 文件

import type { App } from "vue";
import * as ElementPlusIconsVue from "@element-plus/icons-vue";

// 注册所有图标
export function setupElIcons(app: App<Element>) {
  for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
    app.component(key, component);
  }
}

index.ts

export * from "./icons";

在main.ts 中引入

import { createApp } from "vue";
import "@/style.css";
import App from "@/App.vue";

import { setupElIcons } from "@/plugins";

const app = createApp(App);
// 全局注册Element-plus图标
setupElIcons(app);
app.mount("#app");

验证

在HelloWorld.vue 中写入
有来团队后台项目-解析6-LMLPHP

svg

安装

pnpm install vite-plugin-svg-icons -D

引入

main.ts 中引入

// 引入svg
import "virtual:svg-icons-register";

vite.config.ts

// UserConfig,ConfigEnv 都是类型约束
import { UserConfig, ConfigEnv, loadEnv, defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
// 配置vue使用jsx
import vueJsx from "@vitejs/plugin-vue-jsx";

// 以下三项引入是为配置Element-plus自动按需导入
import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";

// 引入svg
import { createSvgIconsPlugin } from "vite-plugin-svg-icons";

// 引入路径
import { resolve } from "path";

// 指定路径 使用 @ 代替/src
const pathSrc = resolve(__dirname, "src");

// https://vitejs.dev/config/

export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
  return {
    resolve: {
      alias: {
        "@": pathSrc,
      },
    },
    plugins: [
      vue(),
      // jsx、tsx语法支持
      vueJsx(),
      AutoImport({
        // 自动导入 Vue 相关函数,如:ref, reactive, toRef 等
        imports: ["vue", "pinia", "vue-router"],
        resolvers: [
          // 自动导入 Element Plus 相关函数,如:ElMessage, ElMessageBox... (带样式)
          ElementPlusResolver(),
        ],
        eslintrc: {
          enabled: true, //  默认 false, true 启用生成。生成一次就可以,避免每次工程启动都生成,一旦生成配置文件之后,最好把 enable 关掉,即改成 false。
          //  否则这个文件每次会在重新加载的时候重新生成,这会导致 eslint 有时会找不到这个文件。当需要更新配置文件的时候,再重新打开
          // 浏览器需要访问所有应用到 vue/element api 的页面才会生成所有自动导入 api 的文件 json
          filepath: "./.eslintrc-auto-import.json",
          // 默认就是 ./.eslintrc-auto-import.json
          globalsPropValue: true,
        },
        vueTemplate: true, // 默认 true 是否在vue 模版中自动导入
        dts: resolve(pathSrc, "typings", "auto-import.d.ts"), //  自动导入组件类型声明文件位置,默认根目录
      }),
      Components({
        resolvers: [
          // 自动导入 Element Plus 组件
          ElementPlusResolver(),
        ],
        dts: resolve(pathSrc, "typings", "components.d.ts"), //  自动导入组件类型声明文件位置,默认根目录
      }),
      // 通过 createSvgIconsPlugin() 入参指定了svg 文件所在的目录和 symbolId。
      createSvgIconsPlugin({
        // Specify the icon folder to be cached
        iconDirs: [resolve(process.cwd(), "src/assets/icons")],
        // Specify symbolId format
        // symbolId
        symbolId: "icon-[dir]-[name]",
      }),
    ],
  };
});

封装svg 组件

src/components 下面新建SvgIcon 文件夹,新建文件 index.vue

<template>
  <svg
    aria-hidden="true"
    :class="['svg-icon', spin && 'svg-icon-spin']"
    :style="'width:' + size + ';height:' + size"
  >
    <use :xlink:href="symbolId" :fill="color" />
  </svg>
</template>

<script setup lang="ts">
/*
名称
大小
颜色
是否loading 效果
*/
const props = defineProps({
  prefix: {
    type: String,
    default: "icon",
  },
  iconClass: {
    type: String,
    required: false,
    default: "",
  },
  color: {
    type: String,
    default: "",
  },
  size: {
    type: String,
    default: "1em",
  },
  spin: {
    type: Boolean,
    default: false,
  },
});

const symbolId = computed(() => `#${props.prefix}-${props.iconClass}`);
</script>

<style scoped>
.svg-icon {
  display: inline-block;
  width: 1em;
  height: 1em;
  overflow: hidden;
  vertical-align: -0.15em; /* 因icon大小被设置为和字体大小一致,而span等标签的下边缘会和字体的基线对齐,故需设置一个往下的偏移比例,来纠正视觉上的未对齐效果 */
  outline: none;
  fill: currentcolor; /* 定义元素的颜色,currentColor是一个变量,这个变量的值就表示当前元素的color值,如果当前元素未设置color值,则从父元素继承 */
}
.svg-icon-spin {
  animation: loadingCircle 1s infinite linear;
}
/* 旋转动画 */
@keyframes loadingCircle {
  0% {
    transform: rotate(0);
  }
  100% {
    transform: rotate(360deg);
  }
}
</style>

测试

HelloWorld.vue 中

<script setup lang="ts">
import { ref } from "vue";

defineProps<{ msg: string }>();

const count = ref(0);
</script>

<template>
  <div>
    <el-button>Default</el-button>
    <el-button type="primary">Primary</el-button>
    <el-button type="success">Success</el-button>
    <el-button type="info">Info</el-button>
    <el-button type="warning">Warning</el-button>
    <el-button type="danger">Danger</el-button>
    <hr />
    <el-icon size="16" color="red">
      <Edit />
    </el-icon>
    <hr />
    <svg-icon icon-class="refresh" spin />
    刷新
  </div>
</template>

<style scoped>
.read-the-docs {
  color: #888;
}
</style>


效果展示

有来团队后台项目-解析6-LMLPHP

03-14 11:02