项目中有用到vue-element-admin,学习方法仍然是造轮子,慢但是能够理解每个细节。记录下遇到的问题和想记录的过程。
安装svg-sprite-loader
yarn add svg-sprite-loader
配置svg-icon的全局组件。在components>SvgIcon下新建index.vue
<template>
<svg :class="svgClass" aria-hidden="true">
<use :xlink:href="iconName" />
</svg>
</template>
<script>
export default {
name: "SvgIcon",
props: {
iconClass: {
type: String,
required: true
},
className: {
type: String,
default: ""
}
},
computed: {
iconName() {
return `#icon-${this.iconClass}`;
},
svgClass() {
if (this.className) {
return "svg-icon " + this.className;
} else {
return "svg-icon";
}
}
}
};
</script>
<style scoped>
.svg-icon {
1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>
在src目录下新建icons目录,在icons目录下新建index.js及icons目录。index.js来注册全局组件。svg文件放在icons下的svg目录中。
index.js内容如下:
import Vue from "vue";
import SvgIcon from "@/components/SvgIcon";
// register globally
Vue.component("svg-icon", SvgIcon);
const req = require.context("./svg", false, /.svg$/);
const requireAll = requireContext => requireContext.keys().map(requireContext);
requireAll(req);
配置svg的loader,在vue.config.js中使用chainWebpack方法。参考vue官方的webpack相关配置及element-ui-vue的源码
"use strict";
const path = require("path");
function resolve(dir) {
return path.join(__dirname, dir);
}
module.exports = {
publicPath: "/",
outputDir: "dist",
assetsDir: "static",
lintOnSave: process.env.NODE_ENV === "development",
productionSourceMap: false,
configureWebpack: {
name: "G-test",
resolve: {
alias: {
"@": resolve("src")
}
}
},
chainWebpack(config) {
config.plugins.delete("preload"); // TODO: need test
config.plugins.delete("prefetch"); // TODO: need test
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();
config.module
.rule("vue")
.use("vue-loader")
.loader("vue-loader")
.tap(options => {
options.compilerOptions.preserveWhitespace = true;
return options;
})
.end();
config
// https://webpack.js.org/configuration/devtool/#development
.when(process.env.NODE_ENV === "development", config =>
config.devtool("cheap-source-map")
);
config.when(process.env.NODE_ENV !== "development", config => {
config
.plugin("ScriptExtHtmlWebpackPlugin")
.after("html")
.use("script-ext-html-webpack-plugin", [
{
// `runtime` must same as runtimeChunk name. default is `runtime`
inline: /runtime..*.js$/
}
])
.end();
config.optimization.splitChunks({
chunks: "all",
cacheGroups: {
libs: {
name: "chunk-libs",
test: /[\/]node_modules[\/]/,
priority: 10,
chunks: "initial" // only package third parties that are initially dependent
},
elementUI: {
name: "chunk-elementUI", // split elementUI into a single package
priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
test: /[\/]node_modules[\/]_?element-ui(.*)/ // in order to adapt to cnpm
},
commons: {
name: "chunk-commons",
test: resolve("src/components"), // can customize your rules
minChunks: 3, // minimum common number
priority: 5,
reuseExistingChunk: true
}
}
});
config.optimization.runtimeChunk("single");
});
}
};
在main.js中引入icons
import "./icons";
此时可以在全局中使用
<span class="svg-container">
<svg-icon icon-class="user" />
</span>