暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Vue.JS:引入外部的图标与字体

Nephilim 2024-03-21
137

Tips:一些记录,一些笔记



2024/03/21

THIRSDAY

Are no shortcuts to any place worth going.

到任何值得去的地方都没有捷径。





01

外部的图标与字体

在前端的页面的开发过程中,图标与字体是非常重要的页面表现形式之一

通常,图标与字体是由专业的矢量设计师提供的,但如果你是个人开发者,你也可以使用到很多开源的免费资源。


阿里巴巴矢量图标库:

https://www.iconfont.cn/

素材库:

字体库:


在接下来的篇幅里会分别讲述「图标资源」与「字体资源」如何引用。


02

「图标资源」的引用


官方文档:

https://www.iconfont.cn/help/detail?spm=a313x.home_index.i3.28.58a33a81ZtiU1x&helptype=code


WEB端的使用有以下几种方式:

  • icon 单个使用

  • unicode 引用

  • font-class 引用

  • symbol 引用


这里,本文演示的是「font-class」的引用方式,会了其中一种方式,其他的方式,根据官方文档的指引也可以轻松掌握。



一、什么是「font-class」

font-class是unicode使用方式的一种变种,主要是解决unicode书写不直观,语意不明确的问题。

与unicode使用方式相比,具有如下特点:

  • 兼容性良好,支持ie8+,及所有现代浏览器。

  • 相比于unicode语意明确,书写更直观。可以很容易分辨这个icon是什么。

  • 因为使用class来定义图标,所以当要替换图标时,只需要修改class里面的unicode引用。

  • 不过因为本质上还是使用的字体,所以多色图标还是不支持的。


二、实现方式(步骤)


(一)在阿里巴巴矢量图标库「申请资源」


首先,搜索你想要的图标,例如,搜索「数据」

可以看到,有很多与「数据」有关的图标;

选择其中你喜欢的,加入购物车:

然后,你就可以在自己的购物车中看到了:

选择「添加至项目」

如果没有项目,需要新建一个项目:

项目创建完成后,图标会被自动加入你新增的这个项目中:

点击「Font Class」并且打开「查看在线链接」:

点击「生成」:

然后,你就得到了一个在线的资源地址(font-class 代码):

这样,在线的资源申请就完成了。


(二)修改本地的Vue项目中的设置


文件「项目根目录/index.html」

完整代码如下:

    <!doctype html>
    <html lang="en">
    <head>
    <meta charset="UTF-8" >
    <link rel="icon" type="image/svg+xml" href="/vite.svg" >
    <meta name="viewport" content="width=device-width, initial-scale=1.0" >
    <title>Vite + Vue</title>


    <!-- 阿里巴巴矢量图标库 -->
    <link rel="stylesheet" href="//at.alicdn.com/t/c/font_4475721_epkqrtcetpj.css" >


    </head>
    <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
    </body>
    </html>



    然后,在具体的页面中引用图标的代码:

    如上的代码中,引入了图标的代码「icon-shuju」

    这个代码,是阿里巴巴矢量图标库网站官方提供的:

    看看效果:

    问题一、图标大小


    可以看到图标引用成功了,就是有点小。


    调整图标的大小:


    再看看效果,图标就变大了:


    问题二、单色图标与多色图标


    不过依然有问题,在阿里官网上看到的图标是彩色的,引用到本地后,变成了黑白的

    这是因为font-class这种方式本质上还是使用的字体,所以不支持多色图标。

    官方也在一开始给出了说明:

    如果希望支持多色图标,可以选择其他的几种引入方式,例如「Symbol」的方式。


    文件「index.html」

      <!doctype html>
      <html lang="en">
      <head>
      <meta charset="UTF-8" >
      <link rel="icon" type="image/svg+xml" href="/vite.svg" >
      <meta name="viewport" content="width=device-width, initial-scale=1.0" >
      <title>Vite + Vue</title>


      <!-- 阿里巴巴矢量图标库 -->
      <!-- Font Class: at.alicdn.com/t/c/font_4475721_epkqrtcetpj.css -->
      <link rel="stylesheet" href="//at.alicdn.com/t/c/font_4475721_epkqrtcetpj.css" >


      <!-- Symbol: at.alicdn.com/t/c/font_4475721_epkqrtcetpj.js -->
      <script src="//at.alicdn.com/t/c/font_4475721_epkqrtcetpj.js"></script>


      </head>
      <body>
      <div id="app"></div>
      <script type="module" src="/src/main.js"></script>
      </body>
      </html>



      页面文件:

      结合本文,请关注「template」与「style」这两个部分的配置

        <template>
        <el-button type="primary" @click="handleClick">Get Data</el-button>
        <hr/>
        <h6>{{ res }}</h6>
        <hr >
        阿里巴巴矢量图标库
        <hr >
        Font Class 引用:单色图标
        <br >
        <i class="iconfont icon-shuju icon-large"></i>
        <hr >
        Symbol 引用:多色图标
        <br >
        <svg class="icon" aria-hidden="true">
        <use xlink:href="#icon-shuju"></use>
        </svg>


        </template>


        <script setup>
        import { getCurrentInstance, ref } from "vue";
        import {getHitokoto} from "@/api/hitokoto/hitokoto.js";


        const { proxy } = getCurrentInstance()
        const res = ref(null)


        async function handleClick() {
        await proxy.$api.hitokoto.getHitokoto().then(
        (result) => {
        console.log(result)
        res.value = result
        }
        )
        }
        </script>


        <style type="text/css">
        .icon {
        width: 5em; height: 5em;
        vertical-align: -0.15em;
        fill: currentColor;
        overflow: hidden;
        }
        .icon-large {
        font-size: 52px;
        }
        </style>

        再次查看页面:

        可以看到,已经看到「多色图标」了


        ———————————————

        以上,就是如何在 Vue.JS 中引入一个外部的图标的操作方式了。


        03

        「字体资源」的引入


        字体资源的引入有两种方式:

        • 在线引入

        • 本地引入


        这里,我选择本地引入。


        首先将我们需要的「字体资源」下载到本地:

        在项目中创建存放「字体资源」的目录,并将字体存放进去:

        创建样式表文件「fonts.scss」

          @charset "UTF-8";
          @font-face {
          font-family: "阿里妈妈刀隶体 Regular";
          //src: url("./AlimamaDaoLiTi/AlimamaDaoLiTi.woff2") format("woff2"), url("./AlimamaDaoLiTi/AlimamaDaoLiTi.woff2") format("woff");
          src: url("./AlimamaDaoLiTi/AlimamaDaoLiTi.woff2");
          font-weight: normal;
          font-style: normal;
          //font-display: swap;
          }


          导入样式文件:


          导入字体的样式文件有几种方式,任选其中一种都可以:

          • vite.config.js

          • main.js

          • style.css


          在我的当前环境中,我选择的是「vite.config.js」,其他几个文件的导入部分我注释了;

          如果希望通过其他两种方式导入,可以对应的解开注释,但注意,三个方式中,三选一。


          下面分别看看这几个文件中的配置:

          文件「main.js」

            // ============================================
            // 引入区域
            // ============================================


            // ---------------
            // 外部支持
            // ---------------


            import { createApp } from 'vue'


            // Element Plus
            import ElementPlus from 'element-plus'
            import 'element-plus/dist/index.css'
            import * as ElementPlusIconsVue from '@element-plus/icons-vue'


            // 自定义组件
            import ComponentsCustom from '@/components/index.js'


            // 路由
            import router from '@/router'


            // AXIOS
            import axios from 'axios'
            import VueAxios from "vue-axios";


            // ---------------
            // 当前代码
            // ---------------


            import './style.css'
            import App from './App.vue'


            // 引入字体
            // import '@/styles/fonts/fonts.scss'


            // API
            import api from '@/api'


            // ============================================
            // 执行区域
            // ============================================


            // 变量声明
            const app = createApp(App)


            // 变量使用


            // --------------------
            // Vue.JS - use


            // - 注册到 Vue.JS 实例:Element Plus
            // 完整引入所有组件:可以传入一个全局配置对象
            app.use(ElementPlus, {
            // size: 'small',
            // zIndex: 2000
            })


            // - 注册所有的 Element Plus 图标
            for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
            app.component(key, component)
            }


            // - 全局注册所有自定义组件
            Object.keys(ComponentsCustom).forEach(
            (key) => {
            app.component(key, ComponentsCustom[key])
            }
            )


            // 路由
            app.use(router)


            // API:全局配置
            app.config.globalProperties.$api = api


            // AXIOS
            app.use(VueAxios, axios)


            // --------------------
            // Vue.JS - mount
            app.mount('#app')



            文件「style.css」

              /*引入字体*/
              /*@import url("styles/fonts/fonts.scss");*/


              :root {
              font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
              line-height: 1.5;
              font-weight: 400;


              color-scheme: light dark;
              color: rgba(255, 255, 255, 0.87);
              background-color: #242424;


              font-synthesis: none;
              text-rendering: optimizeLegibility;
              -webkit-font-smoothing: antialiased;
              -moz-osx-font-smoothing: grayscale;
              }


              a {
              font-weight: 500;
              color: #646cff;
              text-decoration: inherit;
              }
              a:hover {
              color: #535bf2;
              }


              body {
              margin: 0;
              display: flex;
              place-items: center;
              min-width: 320px;
              min-height: 100vh;
              }


              h1 {
              font-size: 3.2em;
              line-height: 1.1;
              }


              button {
              border-radius: 8px;
              border: 1px solid transparent;
              padding: 0.6em 1.2em;
              font-size: 1em;
              font-weight: 500;
              font-family: inherit;
              background-color: #1a1a1a;
              cursor: pointer;
              transition: border-color 0.25s;
              }
              button:hover {
              border-color: #646cff;
              }
              button:focus,
              button:focus-visible {
              outline: 4px auto -webkit-focus-ring-color;
              }


              .card {
              padding: 2em;
              }


              #app {
              max-width: 1280px;
              margin: 0 auto;
              padding: 2rem;
              text-align: center;
              }


              @media (prefers-color-scheme: light) {
              :root {
              color: #213547;
              background-color: #ffffff;
              }
              a:hover {
              color: #747bff;
              }
              button {
              background-color: #f9f9f9;
              }
              }



              文件「vite.config.js」

                // ============================================
                // 引入区域
                // ============================================


                import { defineConfig, loadEnv } from 'vite'
                import vue from '@vitejs/plugin-vue'


                import { fileURLToPath, URL } from 'node:url'
                import * as path from 'path'


                // ElementPlus 按需加载
                import AutoImport from 'unplugin-auto-import/vite'
                import Components from 'unplugin-vue-components/vite'
                import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'


                // ============================================
                // 配置区域
                // ============================================


                // https://vitejs.dev/config/
                export default defineConfig(
                ({ mode }) => {


                // 获取环境配置文件「.env.xxxx」
                const env = loadEnv(mode, process.cwd())


                return {
                plugins: [
                vue(),


                // ElementPlus 按需加载
                AutoImport({
                resolvers: [ElementPlusResolver()],
                }),
                Components({
                resolvers: [
                ElementPlusResolver({
                importStyle: "sass",
                })
                ]
                }),


                ],
                resolve: {
                // 路径别名
                alias: {
                '@': fileURLToPath(
                new URL('./src', import.meta.url),
                )
                }
                },
                css: {
                preprocessorOptions: {
                scss: {
                prependData: ``,
                additionalData: `
                Element Plus 自定义样式
                @use "@/styles/element/index.scss" as *;
                // 自定义字体样式
                @use "@/styles/fonts/fonts.scss" as *;
                `,
                },
                },
                },
                server: {
                host: '0.0.0.0',
                port: Number(env.VITE_APP_PORT),
                open: true,
                proxy: {
                [env.VITE_APP_BASE_API]: {
                target: env.VITE_APP_SERVICE_API,
                changeOrigin: true,
                rewrite: (path) => path.replace(new RegExp("^" + env.VITE_APP_BASE_API), ""),
                },
                },
                },
                }
                }
                )



                最后,在需要使用字体的地方声明即可:

                  <template>
                  <el-button type="primary" @click="handleClick">Get Data</el-button>
                  <hr/>
                  <h6>{{ res }}</h6>
                  <hr />
                  阿里巴巴矢量图标库
                  <hr />
                  Font Class 引用:单色图标
                  <br />
                  <i class="iconfont icon-shuju icon-large"></i>
                  <hr />
                  Symbol 引用:多色图标
                  <br />
                  <svg class="icon" aria-hidden="true">
                  <use xlink:href="#icon-shuju"></use>
                  </svg>
                  <hr />
                  <span class="font">这里使用了「阿里妈妈刀隶体」</span>


                  </template>


                  <script setup>
                  import { getCurrentInstance, ref } from "vue";
                  import {getHitokoto} from "@/api/hitokoto/hitokoto.js";


                  const { proxy } = getCurrentInstance()
                  const res = ref(null)


                  async function handleClick() {
                  await proxy.$api.hitokoto.getHitokoto().then(
                  (result) => {
                  console.log(result)
                  res.value = result
                  }
                  )
                  }
                  </script>


                  <style type="text/css">
                  .icon {
                  width: 5em; height: 5em;
                  vertical-align: -0.15em;
                  fill: currentColor;
                  overflow: hidden;
                  }
                  .icon-large {
                  font-size: 52px;
                  }
                  .font {
                  font-family: "阿里妈妈刀隶体 Regular";
                  font-size: 65px;
                  }
                  </style>


                  看看页面效果:

                  可以看到,字体的引入已经生效了。





                  END




                  温馨提示



                  如果你喜欢本文,请分享到朋友圈,想要获得更多信息,请关注我。


                  文章转载自Nephilim,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                  评论