1. 代码重复三次就是原罪,我一直深刻记着这一点
- 之前我是在 Nav.vue 里是这样引入的
import x from '@/assets/icons/label.svg';
import y from '@/assets/icons/money.svg';
如果 svg 文件一多起来,我就要写很多行一样的代码,我能不能直接 import 一个目录而不用一个个文件去 import ?可以的。
2. 如何 import 一个目录
- 只要加上这几行代码即可
<script lang="ts">
let importAll = (requireContext: __WebpackModuleApi.RequireContext) => requireContext.keys().forEach(requireContext);
try {
importAll(require.context('../assets/icons', true, /.svg$/));
} catch (error) {
error.log(error);
}
</script>
- 注意 Eslint 会报错
如图所示
- 用 Webstorm 的话直接 Alt+Shift+Enter ,Webstorm会自动加上
// eslint-disable-next-line no-undef即可解决
- 此时 icons 目录下的所有 svg 均已 import
如图所示
3. 如何封装成一个组件( icon 组件)
-
就算 import 了整个目录下的 svg 文件,我依然要一个个地用 svg-use 去使用它,代码重复还是出现了,封装成组件就可以解决这个问题。
-
在 components 目录下新建一个组件 icon.vue
-
把之前 Nav.vue 下的 import 代码和 template 标签中重复的代码转移到 icon.vue
如图所示
-
使用 Icon 组件(用 Webstorm 的话输入 <Ico 出现提示后按 tab 即可自动帮我 import Icon 组件) 如图所示
-
因为页面任何地方可能都用到 Icon 组件,需到 main.ts 文件下添加全局,上图的 import 和 components:{Icon} 可以去掉了。
import Icon from '@/components/Icon.vue';
Vue.component('Icon', Icon);
如图所示
- 此时可以用 Icon 组件引入 svg 了,但是因为之前在 Icon.vue 中的 template 里写死了
<use xlink:href="#label">,还需要修改一下达到引入其他 svg 的目标。
4. 给 Icon 组件添加外部属性即可
- 在外部属性 export default 添加一个 name 属性(不用 id 是因为跟 div 的 id 有冲突)
export default {
props:['name'],
name: 'icon'
};
如图所示
- 接下来需要把 name 放到之前写死的 template 标签里,需要用到 v-bind,因为 name 是 money/labels/statistics,需要在前面加 # 才可以,写法如下
<template>
<svg>
<use :xlink:href="'#'+ name"/>
</svg>
</template>
注:Vue 默认属性名前可以有冒号
如图所示
5. 此时终于可以正常使用 Icon 组件引入 svg了
- 给对应的 Icon 加上相应的 name
如图所示
效果如下图