• 如何在 vue 中使用 svg symbols


    安装svg-sprite-loader插件

    npm install svg-sprite-loader -D

    或者

    yarn add svg-sprite-loader -D

    在vue.config.js中配置 svg-sprite-loader

    1. const path = require('path');
    2. module.exports = {
    3. chainWebpack:config =>{
    4. const dir = path.resolve(__dirname,'src/assets/icons')
    5. config.module
    6. .rule('svg-sprite')
    7. .test(/\.svg$/)
    8. .include.add(dir).end() //设置 icons 目录走 svg-sprite 规则
    9. .use('svg-sprite-loader').loader('svg-sprite-loader').options({extract : false}).end()
    10. .use('svgo-loader').loader('svgo-loader')
    11. .tap(options => ({...options,plugins:[{removeAttrs:{attrs:'fill'}}]})).end()//安装插件去除svg中的fill属性
    12. config.plugin('svg-sprite').use(require('svg-sprite-loader/plugin'),[{plainSprite: true}])
    13. config.module.rule('svg').exclude.add(dir)//其他svg loader 排除 icons 目录
    14. }
    15. }

    也可以这么配置

    1. const { defineConfig } = require('@vue/cli-service')
    2. // 加在头部
    3. const path = require('path')
    4. function resolve (dir) {
    5. return path.join(__dirname, dir)
    6. }
    7. module.exports = defineConfig({
    8. transpileDependencies: true,
    9. chainWebpack (config) {
    10. config.plugins.delete('prefetch')
    11. // set svg-sprite-loader
    12. config.module
    13. .rule('svg')
    14. .exclude.add(resolve('src/assets/icons'))
    15. .end()
    16. config.module
    17. .rule('icons')
    18. .test(/\.svg$/)
    19. .include.add(resolve('src/assets/icons'))
    20. .end()
    21. .use('svg-sprite-loader')
    22. .loader('svg-sprite-loader')
    23. .options({
    24. // symbolId: 'icon-[name]'
    25. symbolId: '[name]'
    26. })
    27. .end()
    28. }
    29. })

    注意:src/assets/icons这个文件夹放着你的svg文件

    封装IconSvg.vue通用组件

    1. <template>
    2. <div class="icon-wrapper">
    3. <svg class="icon" aria-hidden="true">
    4. <use :href="iconName">use>
    5. svg>
    6. div>
    7. template>
    8. <script>
    9. export default {
    10. name: 'IconSvg',
    11. props: {
    12. name: String,
    13. prefix: {
    14. type: String,
    15. default: 'icon-'
    16. }
    17. },
    18. computed: {
    19. iconName() {
    20. // return `#${this.prefix}${this.name}`
    21. return `#${this.name}`
    22. }
    23. }
    24. }
    25. script>
    26. <style scoped>
    27. .icon-wrapper {
    28. display: inline-block;
    29. }
    30. .icon {
    31. width: 100%;
    32. height: 100%;
    33. vertical-align: -0.15em;
    34. fill: currentColor;
    35. overflow: hidden;
    36. }
    37. style>

    加载所有的svg静态资源,并且把 IconSvg注册到全局组件当中

    1. import Vue from 'vue'
    2. import App from './App.vue'
    3. import router from './router'
    4. // 引入本地的svg文件
    5. // 定义一个加载目录的函数
    6. const requireAll = requireContext => requireContext.keys().map(requireContext)
    7. const req = require.context('./assets/icons', false, /\.svg$/)
    8. // 加载目录下的所有的 svg 文件
    9. requireAll(req)
    10. // 全局注册IconSvg组件
    11. const IconSvg = () => import('./components/svg/IconSvg');
    12. const components = {
    13. IconSvg
    14. }
    15. Object.keys(components).forEach(item => {
    16. Vue.component(item, components[item])
    17. })
    18. Vue.config.productionTip = false
    19. new Vue({
    20. router,
    21. render: h => h(App)
    22. }).$mount('#app')

    使用

    使用的话有多种形式,我们一个一个来看。

    1、使用自己编写的svg文件

            在src/assets/icons文件夹下面创建circle.svg(一定是这个文件夹,因为这个文件夹下的svg文件会被你的svg插件解析)

    1. "1.0"?>
    2. <svg viewBox="0 0 120 120" version="1.1"
    3. xmlns="http://www.w3.org/2000/svg">
    4. <circle cx="60" cy="60" r="50"/>
    5. svg>

            经过svg-sprite-loader插件的解析,你在html里面可以看到有个id为circle(和svg名称一样)的一个symbol标签挂载在svg标签下面

             这个时候直接使用就可以了

            

    1. <template>
    2. <div class="home">
    3. <IconSvg name="circle"/>
    4. div>
    5. template>
    6. <script>
    7. export default {
    8. name: 'HomeView',
    9. components: {
    10. }
    11. }
    12. script>
    13. <style scoped>
    14. style>

            

     2、将svg标签封装到一个vue文件中

            创建SvgList.vue组件

    1. <template>
    2. <svg width="0" height="0" preserveAspectRatio="none">
    3. <defs>
    4. <symbol id="icon-circle" viewBox="0 0 200 200">
    5. <circle cx="60" cy="60" r="50" />
    6. symbol>
    7. <symbol id="icon-circle" viewBox="0 0 200 200">
    8. <rect width="10" height="10">
    9. <animate attributeName="rx" values="0;5;0" dur="10s" repeatCount="indefinite" />
    10. rect>
    11. symbol>
    12. <symbol id="icon-circle" viewBox="0 0 200 200">
    13. <rect x="10" y="10" width="100" height="100"/>
    14. symbol>
    15. defs>
    16. svg>
    17. template>
    18. <script>
    19. export default {
    20. };

            使用如下

    1. <template>
    2. <div class="home">
    3. <svg-list />
    4. <IconSvg name="icon-circle" class="icon1"/>
    5. <IconSvg name="icon-rect" class="icon1"/>
    6. div>
    7. template>
    8. <script>
    9. import SvgList from '../components/SvgList.vue'
    10. export default {
    11. name: 'HomeView',
    12. components: {
    13. SvgList
    14. }
    15. }
    16. script>
    17. <style scoped>
    18. .icon1 {
    19. width: 100px;
    20. height:100px;
    21. color: red;
    22. }
    23. style>

            

    3、使用iconfont的svg代码

             在src/assets/icons这个文件夹下面去创建heart.svg(一定是这个文件夹,因为这个文件夹下的svg文件会被你的svg插件解析)

            

    1. <svg t="1660895988570" class="icon" viewBox="0 0 1171 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1570" width="200" height="200">
    2. <path d="M1001.6 153.6s0-3.2 0 0c-118.4-118.4-304-121.6-425.6-12.8-121.6-108.8-307.2-105.6-422.4 9.6-118.4 118.4-121.6 310.4-3.2 428.8l3.2 3.2 355.2 352c38.4 38.4 99.2 38.4 137.6 0l355.2-352c118.4-118.4 118.4-310.4 0-428.8z m-115.2 249.6c-9.6 0-16-6.4-16-16 0-57.6-48-105.6-105.6-105.6-9.6 0-16-6.4-16-16s6.4-16 16-16c76.8 0 137.6 60.8 137.6 137.6 0 9.6-6.4 16-16 16z" fill="#343231" p-id="1571">
    3. path>
    4. svg>

            使用

    1. <template>
    2. <div class="home">
    3. <IconSvg name="heart" class="icon1"/>
    4. div>
    5. template>
    6. <script>
    7. export default {
    8. name: 'HomeView',
    9. components: {
    10. }
    11. }
    12. script>
    13. <style scoped>
    14. .icon1 {
    15. width: 100px;
    16. height:100px;
    17. color: chocolate;
    18. }
    19. style>

            效果

             在这里你会遇到一个问题,那就是给这个svg改颜色改不掉,你只要把svg标签里的fill属性去掉就可以了,或者把fill属性设置成none。还有一个stroke轮廓颜色也是可以设置的。

    4、直接引入整个iconfont的svg图片

            生成symbol代码

            

             在index.html中引入上面的symbol代码

    1. html>
    2. <html lang="">
    3. <head>
    4. <meta charset="utf-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width,initial-scale=1.0">
    7. <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    8. <title><%= htmlWebpackPlugin.options.title %>title>
    9. head>
    10. <body>
    11. <noscript>
    12. <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.strong>
    13. noscript>
    14. <div id="app">div>
    15. <script src="//at.alicdn.com/t/c/font_1803779_bgkm96l1xgp.js">script>
    16. body>
    17. html>

            看控制台已经全部引入进来了

            使用

    1. <template>
    2. <div class="home">
    3. <IconSvg name="iconjiahao" class="icon1"/>
    4. <IconSvg name="iconqicheqianlian-1" class="icon2"/>
    5. <IconSvg name="iconxinaixin" class="icon2"/>
    6. <IconSvg name="iconjinzhi" class="icon1"/>
    7. <IconSvg name="iconcart" class="icon1"/>
    8. div>
    9. template>
    10. <script>
    11. export default {
    12. name: 'HomeView',
    13. components: {
    14. }
    15. }
    16. script>
    17. <style scoped>
    18. .icon1 {
    19. width: 100px;
    20. height:100px;
    21. color: chocolate;
    22. }
    23. .icon2 {
    24. width: 100px;
    25. height:100px;
    26. color: darkorange;
    27. }
    28. style>

    效果

    提示:当然你也可以上传svg图片到iconfont平台,然后再下载下来使用,但是在下载下来的时候一定要去去除颜色并提交,这样你的svg图片就可以随心所欲的改颜色了

  • 相关阅读:
    统信UOS 1060上通过Fail2Ban来Ban IP
    圆梦字节之后,我收集整理了这份“2021秋招常见Java面试题汇总”
    OpenShift AI - 部署并使用 LLM 模型
    算法 - 二分
    Django(6)路由
    适用于嵌入式arm的ffmpeg编解码
    经纬度/墨卡托坐标互转
    研究生如何学习与科研的几点建议——来自一枚菜博的愚见
    Shell脚本之正则表达式详解
    羊了个羊的接口测试
  • 原文地址:https://blog.csdn.net/cai_niao5623/article/details/126424871