请教下各位大佬,我接口拿到后台返回 icon 的 name:string ,如何做动态引入呢?
之前都是用的 iconfont ,不需要单独 import ,这回改用 SVG ICON 犯了难。
vue3/vite/naive-ui/xions
1
daysv 2022-09-07 14:59:12 +08:00
啥动态不动态的, 统统放 public 当资源
|
2
Carseason 2022-09-07 15:04:03 +08:00
import("xxx")
|
3
colatea 2022-09-07 15:11:29 +08:00
main.js
import * as ElementPlusIconsVue from '@element-plus/icons-vue' ... import { Search } from "@element-plus/icons-vue"; ... components: { Search }, ... <el-icon> <Search /> </el-icon> |
4
haodaking 2022-09-07 15:28:22 +08:00 1
https://codesandbox.io/s/magical-carson-n6540i?file=/src/Icon.vue
Icon.vue <script lang="ts"> import { defineComponent, computed, defineAsyncComponent } from "vue"; export default defineComponent({ props: ["icon"], setup(props) { const iconCompoent = computed(() => { return defineAsyncComponent(async () => { return (await import("@vicons/ionicons5"))[props.icon]; }); }); return { iconCompoent, }; }, }); </script> <template> <n-icon :component="iconCompoent" /> </template> 使用 Demo.vue <template> <Icon icon="GameController" /> <Icon icon="GameController" size="40" color="#0e7a0d" /> </template> <script lang="ts"> import { defineComponent } from "vue"; import Icon from "./Icon.vue"; export default defineComponent({ components: { Icon, }, }); </script> |
5
zcf0508 2022-09-07 15:56:09 +08:00
打包的时候如果不知道要使用的 svg 那是不能打包进去的,所以解决办法要么就是打包的时候把所有的 svg 文件都打包进去,要么就单独找个 cdn 引用进来
|
6
thinkershare 2022-09-07 16:49:04 +08:00 1
你有 2 个选择, 第一个是再前端全部将 SVG 一次性全部导入, 然后定义好 SymbolId, 根据 name 转换到 SymbolId, 然后使用, 这种方式本身 SVG 图片是一次性导入到前端的, 只是显示什么 icon 是动态的. 另外一种就是根据 SVG 名称转换为完整的 cdn 提供的 https://xxx.svg 这种资源路径, 然后再 svg 标签中, href 直接引用.
|
7
dengqing 2022-09-07 18:36:19 +08:00 via iPhone
|
8
zhuweiyou 2022-09-07 22:16:37 +08:00
import.meta.globEager
|
9
JayZXu 2022-09-08 08:23:17 +08:00
目前用的这个包 vite-plugin-svg-icons
https://github.com/vbenjs/vite-plugin-svg-icons/blob/main/README.zh_CN.md 使用逻辑跟 webpack 的 svg 使用差不多,把 svg 放在文件夹里面就能生成对应的 icon name |
10
justin2018 2022-09-26 19:25:28 +08:00
### Vue 中优雅使用 SVG
#### 相关文章 在 vue 项目中优雅的使用 Svg - 掘金 https://juejin.cn/post/6844903697999200263 在 vue3+vite 项目中使用 svg - 掘金 https://juejin.cn/post/6932037172178616334 通过 vite-plugin-svg-icons 插件封装 SvgIcon 组件 - 掘金 https://juejin.cn/post/7094060278475653128 --- #### 使用`vite-plugin-svg-icons`插件 ##### 安装插件 ```shell // 安装插件 npm install svg-sprite-loader -D # via yarn yarn add svg-sprite-loader -D // 如果报错 需要安装“fast-glob” yarn add fast-glob -D ``` ##### 封装 SvgIcon 组件 ```javascript <template> <svg :class="svgClass" v-bind="$attrs" :style="{ color: color }"> <use :xlink:href="iconName" /> </svg> </template> <script> import { defineComponent, computed } from "vue"; export default defineComponent({ name: "SvgIcon", props: { name: { type: String, required: true, }, color: { type: String, default: "#333", }, }, setup(props) { const iconName = computed(() => `#icon-${props.name}`); const svgClass = computed(() => { console.log(props.name, "props.name"); if (props.name) { return `svg-icon icon-${props.name}`; } return "svg-icon"; }); return { iconName, svgClass, }; }, }); </script> <style scoped> .svg-icon { width: 1em; height: 1em; fill: currentColor; vertical-align: middle; } </style> ``` ##### 配置插件 ```javascript // 配置 vite.config.js import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import { createSvgIconsPlugin } from 'vite-plugin-svg-icons' import { resolve } from 'path' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ vue(), createSvgIconsPlugin({ iconDirs: [resolve(process.cwd(), 'src/assets/svg')], symbolId: 'icon-[dir]-[name]', }) ], }) // 配置 main.js import 'virtual:svg-icons-register' const app = createApp(App); app .component("svg-icon", SvgIcon) .mount('#app'); ``` ##### 使用插件 ```vue <script setup> import HelloWorld from "./components/HelloWorld.vue"; import SvgIcon from "./components/SvgIcon.vue"; </script> <template> <div> <a href="https://vitejs.dev" target="_blank"> <img src="/vite.svg" class="logo" alt="Vite logo" /> </a> <a href="https://vuejs.org/" target="_blank"> <img src="./assets/vue.svg" class="logo vue" alt="Vue logo" /> </a> </div> <HelloWorld msg="Vite + Vue" /> <SvgIcon name="tree" /> </template> <style scoped> .logo { height: 6em; padding: 1.5em; will-change: filter; } .logo:hover { filter: drop-shadow(0 0 2em #646cffaa); } .logo.vue:hover { filter: drop-shadow(0 0 2em #42b883aa); } </style> ``` |