
我才不要別人喜歡的
我要自己喜歡的
───────────────── By Opshell
vite-plugin-svg-icons因為想要隨時可以增減icon,
然後挑自己喜歡的Icon來用,
所以原先在Vue_clil的時候有使用svg-sprite-loader,
但svg-sprite-loader是基於webpack打包的,
現在換到Vite我們需要換一套:
 yarn add vite-plugin-svg-icons -D
修改
vite.comfig.ts:
 // vite.comfig.ts
 import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
 export default () => {
   return {
      plugins: [
         createSvgIconsPlugin({
            iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')], // 指定需要占存的Icon目錄
            symbolId: '[name]', // 指定symbolId格式 預設:'icon-[dir]-[name]
            inject: 'body-last', // | 'body-first' sprite插入位置
            customDomId: '__svg__icons__dom__', // 自訂 Dom ID
         }),
 //... 以下省略
src/main.ts在
src/main.ts內引用:
 // src/main.ts
 import 'virtual:svg-icons-register';
tsconfig.json用Typescript,還需要在
tsconfig.json内新增:
 // tsconfig.json
 {
   "compilerOptions": {
      "types": ["vite-plugin-svg-icons/client"]
   }
 }
把要用的svg都丟到
src/assets/icon。
在
src/components裡新增el-svgIcon.vue
這個部分不太需要改什麼,使用方式沒啥區別,
畢竟原理一樣
 <div v-if="href == ''" class="icon">
     <svg class="svg">
         <use :xlink:href="`#${name}`" />
     </svg>
 </div>
src/views裡新增 IconList.vue做一個icon列表,圖像化的方式,
之後後台使用更方便,原碼:
 // IconList.vue(Javascript)
 import { onMounted, ref } from "vue";
 import { useStore } from "vuex";
 import elSvgIcon from "../components/el-svgIcon.vue";
 export default {
     components: { elSvgIcon },
     setup() {
         const store = useStore();
         const states = useState(["userData"]);
         const iconList = ref([]);
         onMounted(() => {
             iconList.value = [];
             let spriteSvg = [...document.getElementById('__SVG_SPRITE_NODE__').children];
             spriteSvg.forEach(svgDom => {
                 iconList.value.push(svgDom.id);
             });
         });
         store.commit('endLoading');
         return {
             ...states,
             iconList
         };
     },
 };
Script 標籤改成這樣
<script setup lang="ts">
並且修改下面這些部分:
 import { useStore } from '@/store';
 import { Ref } from '@vue/reactivity'; // Ref的型別
 const store = useStore();
 const iconList: Ref<string[]> = ref([]);
 onMounted(() => {
     const spriteSvg = document.getElementById('__svg__icons__dom__');
     if (spriteSvg != null) {
         let svgList = Array.from(spriteSvg.children); // 2488
         svgList.forEach((svgDom) => {
             iconList.value.push(svgDom.id);
         });
     }
 });
 store.commit('route/endLoading');
這次的改寫過程遇到了好多問題:
這個還行,看官方文件就可以解決了。
用型別檢測做個導流。
錯誤代碼(TS2488),
這個實在很奇怪,理論上來說Array.from(spriteSvg.children)
等價於[...spriteSvg.children]
但是就是會報錯,打死解不開,求有解的大大解惑。

iconList在Tamplate中型別錯誤這個錯誤也是很奇怪,各種寫法都一樣的結果,
猜測是莫名地抓不到暴露的vue,但是該有的設定都跑了,
也查不到相關的錯誤,雖然能成功執行就是了。

※ 3和4的錯誤一直沒有其他想法,
不過編譯的時候根本不會報錯,
Ops甚至覺得根本是Error Len在亂叫,
期待有大大解惑,或者哪天我懂了再回來改文章。
這邊遇到了好多神奇的問題,
雖然大部分都沒有解開,
只是找了個方法繞過去,
但過程中學到了很多東西,
也算是獲益良多。