vue中使用svg-icon遇到的坑及解决
作者:maxiaoxin1314
这篇文章主要介绍了vue中使用svg-icon遇到的坑及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
1.每次在项目中使用icon的图标时
总是觉得引入很长的路径很麻烦,最近发现一个插件挺好用的,svg-sprite-loader
svg-sprite-loader实际上是把所有的svg打包成一张雪碧图,
再通过<use xlink:href="#xxx"/>来显示你所需的icon,
但是在使用的过程总会出现问题;
2.安装依赖
npm i svg-sprite-loader --save
3.vue中vue.config.js中的配置
chainWebpack(config) { const svgRule = config.module.rule("svg"); // 清除已有的所有 loader。 svgRule.uses.clear(); svgRule .test(/\.svg$/) .include.add(path.resolve(__dirname, "src/assets/icons")) // 文件目录 .end() .use("svg-sprite-loader") .loader("svg-sprite-loader") .options({ symbolId: "icon-[name]", }); const fileRule = config.module.rule("file"); fileRule.uses.clear(); fileRule .test(/\.svg$/) .exclude.add(path.resolve(__dirname, "src/assets/icons")) .end() .use("file-loader") .loader("file-loader"); },
或者只需要简单的配置:
chainWebpack(config) { config.module .rule("svg") .exclude.add(resolve("src/icons")) .end(); config.module .rule("icons") .test(/\.svg$/) .include.add(resolve("src/icons")) .end() .use("svg-sprite-loader") .loader("svg-sprite-loader") .options({ symbolId: "icon-[name]", }) .end(); },
以上的两种试过都是可以的。
4.在src文件目录下
新建一个icons文件,icons里面的svg文件是需要用到的svg矢量图
index.js文件:
import Vue from "vue"; import SvgIcon from "@/components/SvgIcon"; // svg component // register globally Vue.component("svg-icon", SvgIcon); const req = require.context("./svg", false, /\.svg$/); const requireAll = (requireContext) => requireContext.keys().map(requireContext); requireAll(req);
5.在components下面新建一个SvgIcon文件
index.vue文件:
<template> <!-- <div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" /> --> <svg :class="svgClass" aria-hidden="true"> <use :xlink:href="iconName" rel="external nofollow" /> </svg> </template> <script> // doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage import { isExternal } from "@/utils/validate"; export default { name: "SvgIcon", props: { iconClass: { type: String, required: true, }, className: { type: String, default: "", }, }, computed: { isExternal() { return isExternal(this.iconClass); }, iconName() { return `#icon-${this.iconClass}`; }, svgClass() { if (this.className) { console.log(this.className); return "svg-icon " + this.className; } else { return "svg-icon"; } }, styleExternalIcon() { return { mask: `url(${this.iconClass}) no-repeat 50% 50%`, "-webkit-mask": `url(${this.iconClass}) no-repeat 50% 50%`, }; }, }, }; </script> <style scoped> .svg-icon { width: 1em; height: 1em; vertical-align: -0.15em; fill: currentColor; overflow: hidden; color: #fff; } .svg-external-icon { background-color: currentColor; mask-size: cover !important; display: inline-block; } </style>
6.在main.js中引用就行
7.在需要用到的组件中使用
8.vue-cli2.0下找到build下webpack.base.config.js
在module中的rule下加入下面的规则:
{ test: /\.svg$/, loader: "svg-sprite-loader", include: [resolve("src/icons")], options: { symbolId: "icon-[name]" } },
如果存在file-loader的规则还需要更改路径:
{ test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: "url-loader", options: { limit: 10000, name: utils.assetsPath("img/[name].[hash:7].[ext]") }, exclude: [resolve("src/icons")]//加入这句 },
应该就不会有什么问题了
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。