欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

buildAdmin開源項目引入四種圖標(biāo)方式詳解

 更新時間:2023年02月01日 15:52:15   作者:Sapper  
這篇文章主要為大家介紹了buildAdmin開源項目引入四種圖標(biāo)方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

正文

在項目開發(fā)中,我們經(jīng)常使用可能都是UI組件庫里的圖標(biāo),當(dāng)然由于業(yè)務(wù)需要,可能當(dāng)前圖標(biāo)庫沒有我們需要的圖標(biāo)這時候就需要引入其它圖標(biāo)庫的圖標(biāo),比如iconfont、FontAweSome、本地圖標(biāo)庫。在了解引入這些圖標(biāo)庫之前,我們先學(xué)習(xí)一下各種圖標(biāo)庫的引入使用:

Element-Plus:由于elemen官方已經(jīng)把圖標(biāo)封裝成了組件,所以當(dāng)我們引入圖標(biāo)的時候,需要全局聲明組件。

import * as Icons from '@element-plus/icons';
const app = createApp(App);
// 全局注冊圖標(biāo),犧牲一點性能
for (let i in Icons) {
// 官方圖標(biāo)名稱首字母都是大寫,所以轉(zhuǎn)為小寫,并命名組件未el-icon-圖標(biāo)名
app.component(`el-icon-${toLine(i)}`, (Icons as any)[i]);
}
// 組件中使用圖標(biāo)
<el-icon-user />

Iconfont:阿里巴巴圖標(biāo)庫,通過創(chuàng)建一個項目目錄,然后把我們需要的圖標(biāo)添加進去,然后在項目中引入圖標(biāo)目錄的cdn(三種方式之一:css代碼、css鏈接、js鏈接)就可以使用了,如果沒有特殊處理一般是在項目的index.html中引入相關(guān)鏈接,css代碼可以在根目錄的樣式文件中引入。然后就可以在項目中使用:

<i class="iconfont icon-user"></i>

FontAwesome:一個比較好用的字體圖標(biāo)庫,可以直接通過cdn引入,也可以通過安裝package包引入,然后就可以使用了:

英文官網(wǎng):fontawesome.com/search

中文網(wǎng):fontawesome.com.cn/

<i class="fa fa-user"></i>

引用本地圖標(biāo):一般使用svg格式圖標(biāo),因為svg性能好,相對于其它格式,它體積更小,可以任意放大圖形顯示,不以犧牲圖標(biāo)質(zhì)量為代價,項目中是不能直接加載svg格式,需要額外插件實現(xiàn)(后面會詳細(xì)介紹)。

<svg class="svg-icon icon" style="width: 1em;height: 1em;color: black;">
<use href="#local-vue" rel="external nofollow"  rel="external nofollow"  />
</svg>

為了方便維護以及擴展,我們可以把四種圖標(biāo)封裝為統(tǒng)一組件使用,在封裝前我們需要明確三點:

  • 獲取所有圖標(biāo)。
  • 實現(xiàn)圖標(biāo)可復(fù)制,復(fù)制就可用的原則。
  • 圖標(biāo)使用統(tǒng)一組件。

在學(xué)習(xí)各類的圖標(biāo)庫之前我們先了解一下如何封裝一下圖標(biāo)共用組件,它向外暴露的名稱是Icon:

實現(xiàn)組件健壯性、易維護:支持圖標(biāo)名稱(name)、圖標(biāo)顏色(color)、圖標(biāo)大?。╯ize)三要素的自定義。四種圖標(biāo)格式引入為element-plus(el-icon-iconName)、iconfont(iconfont iconName)、fontawesome(fa fa-iconName)、本地圖標(biāo)(local-iconName),iconName是圖標(biāo)名稱。

props: {
name: {
  type: String,
  required: true,
},
size: {
  type: String,
  default: '30px',
},
color: {
  type: String,
  default: '#00000',
},
},
// 處理樣式,去掉多余px命名
const iconStyle = computed((): CSSProperties => {
  const { size, color } = props;
  let s = `${size.replace('px', '')}px`;
  return {
    fontSize: s,
    color: color,
  };
});

兼容上面四種圖標(biāo)實現(xiàn):通過Vue3的setup的返回值中使用渲染函數(shù)實現(xiàn),不需要在template中定義標(biāo)簽使用,分三種情況。

createVNode函數(shù):創(chuàng)建虛擬節(jié)點,從左到右有三個參數(shù):html標(biāo)簽名稱或組件(String)、標(biāo)簽屬性(Object)、嵌套標(biāo)簽定義(Array)。

對于element-plus圖標(biāo)的渲染:官方是通過el-icon標(biāo)簽內(nèi)直接使用圖標(biāo)組件,所以創(chuàng)建虛擬節(jié)點標(biāo)簽就是el-icon,由于圖標(biāo)組件是嵌套的,所以需要用到第三參數(shù)。

setup(props) {
    // 當(dāng)前引入的是element-plus圖標(biāo)
    if (props.name.indexOf('el-icon-') === 0) {
      return () =>
        createVNode(
          'el-icon',
          { class: 'icon el-icon', style: iconStyle.value },
          [createVNode(resolveComponent(props.name))]
        );
    }
 }

對于iconfont、fontawesome圖標(biāo)的渲染:由于使用這兩種的圖標(biāo)的標(biāo)簽都是i,它們唯一不同就是圖標(biāo)名稱的命名所以可以共用同一個渲染函數(shù)。

setup(props){
 // 當(dāng)前引入的是iconfont或fontawesome圖標(biāo)
 if (props.name.indexOf('local-') === 0 || isExternal(props.name)) {
 return () =>
    createVNode('i', {
      class: [props.name, 'icon'],
      style: iconStyle.value,
    });
  }
}

對于本地svg圖標(biāo)的渲染:直接引入本地封裝的svg組件,把這個組件當(dāng)作渲染標(biāo)簽,這里圖標(biāo)命名以local-iconName格式引入的。

setup(props){
 // 當(dāng)前引入的是本地svg圖標(biāo)
 if (props.name.indexOf('local-') === 0 || isExternal(props.name)) {
  return () =>
    createVNode(svg, {
      name: props.name,
      size: props.size,
      color: props.color,
    });
  }
}

最終就可以通過這樣使用圖標(biāo):

<Icon name="" color="" size=""/>

其實上面就已經(jīng)實現(xiàn)了四種圖標(biāo)的類型統(tǒng)一封裝,一致使用。接下來為了更方便獲取圖標(biāo),我們把所有圖標(biāo)封裝起來就可以直接cv使用了。

點擊實現(xiàn)cv方式:通過點擊圖標(biāo)傳入我們想要復(fù)制的內(nèi)容,一般都是整個組件的字符串。

export const useCopy = (text: string) => {
  let input = document.createElement('input'); // 創(chuàng)建輸入框
  input.value = text; // 給輸入框value賦值
  document.body.appendChild(input); // 追加到body里面去
  input.select(); // 選擇輸入框的操作
  document.execCommand('Copy'); // 執(zhí)行復(fù)制操作
  document.body.removeChild(input); // 刪除加入的輸入框
  ElMessage.success('復(fù)制成功!');
};

引入Element-Plus圖標(biāo)庫

import * as elIcons from '@element-plus/icons-vue';
// 獲取所有Element-Plus圖標(biāo)組件名稱,如搜索圖標(biāo)Search
export function getElementPlusIconfontNames() {
  return new Promise<string[]>((resolve, reject) => {
    nextTick(() => {
      const iconfonts = [];
      const icons = elIcons as any;
      // 遍歷添加icons組件名稱
      for (const i in icons) {
        iconfonts.push(icons[i].name);
      }
      if (iconfonts.length > 0) {
        resolve(iconfonts);
      } else {
        reject('No ElementPlus Icons');
      }
    });
  });
}

引入Iconfont圖標(biāo)庫

先加載圖標(biāo)樣式表:

const cssUrls: Array<string> = [
  '//at.alicdn.com/t/c/font_3846007_vf3shrhbpya.css', // 阿里圖標(biāo)庫cs,每添加一次圖標(biāo)都需要更換
  '//cdn.bootcdn.net/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css', // font-awesome的css
];
export default function init() {
  // 遍歷加載圖標(biāo)鏈接樣式
  if (cssUrls.length > 0) {
    cssUrls.map((v) => {
      loadCss(v);
    });
  }
}
// 通過創(chuàng)建link標(biāo)簽引入樣式鏈接
export function loadCss(url: string): void {
  const link = document.createElement('link'); // 創(chuàng)建link標(biāo)簽
  link.rel = 'stylesheet';
  link.href = url;
  // 是否采用跨域的方式加載。它可以取兩個值
  // anonymous(跨域請求時,不發(fā)送用戶憑證,主要是 Cookie)
  // use-credentials(跨域時發(fā)送用戶憑證)。
  link.crossOrigin = 'anonmous';
  document.getElementsByTagName('head')[0].appendChild(link);
}

獲取當(dāng)前頁面中從指定域名加載到的樣式表內(nèi)容:在調(diào)用這個函數(shù)之前必須要先引入樣式。

// 獲取樣式表內(nèi)容
function getStylesFromDomain(domain: string) {
  const sheets = [];
  const styles: StyleSheetList = document.styleSheets;
  for (const key in styles) {
    if (styles[key].href && (styles[key].href as string).indexOf(domain) > -1) {
      sheets.push(styles[key]);
    }
  }
  return sheets;
}

調(diào)用這個函數(shù)之后就可以獲取到當(dāng)前圖標(biāo)庫相關(guān)樣式表內(nèi)容,我們的目的就是拿到圖標(biāo)名稱,可以提取rules數(shù)組內(nèi)的樣式名稱就可以拿到所有圖標(biāo)名稱了。

// 獲取所有iconfont圖標(biāo)庫圖標(biāo)名稱
export function getIconfontNames() {
  init();
  return new Promise<string[]>((resolve, reject) => {
    nextTick(() => {
      const iconfonts = [];
      const sheets = getStylesFromDomain('at.alicdn.com');
      for (const key in sheets) {
        const rules: any = sheets[key].cssRules;
        for (const k in rules) {
          // .表示匹配除換行符 \n 之外的任何單字符
          // *表示單個字符匹配任意次
          if (
            rules[k].selectorText &&
            /^\.icon-(.*)::before$/g.test(rules[k].selectorText)
          ) {
            // 去掉樣式的.符號以及::before
            iconfonts.push(
              `${rules[k].selectorText
                .substring(1, rules[k].selectorText.length)
                .replace(/\:\:before/gi, '')}`
            );
          }
        }
      }
      if (iconfonts.length > 0) {
        resolve(iconfonts);
      } else {
        reject('No Iconfont style sheet');
      }
    });
  });
}

引入FontAwesome圖標(biāo)庫

先加載圖標(biāo)樣式表:也就是直接調(diào)用init函數(shù),加載相應(yīng)的樣式鏈接。

獲取當(dāng)前頁面中從指定域名加載到的樣式表內(nèi)容:如下圖所示。

export function getAwesomeIconfontName() {
  init();
  return new Promise<string[]>((resolve, reject) => {
    nextTick(() => {
      const iconfonts = [];
      // 獲取所有圖標(biāo)名稱
      const sheets = getStylesFromDomain(
        'cdn.bootcdn.net/ajax/libs/font-awesome/'
      );
      for (const key in sheets) {
        const rules: any = sheets[key].cssRules;
        // 處理方法與iconfont一致,只不過名稱不一樣
        for (const k in rules) {
          if (
            rules[k].selectorText &&
            /^\.fa-(.*)::before$/g.test(rules[k].selectorText)
          ) {
            if (rules[k].selectorText.indexOf(', ') > -1) {
              // selectorText里有多個圖標(biāo),只提取第一個
              const iconNames = rules[k].selectorText.split(', ');
              iconfonts.push(
                `${iconNames[0]
                  .substring(1, iconNames[0].length)
                  .replace(/\:\:before/gi, '')}`
              );
            } else {
              iconfonts.push(
                `${rules[k].selectorText
                  .substring(1, rules[k].selectorText.length)
                  .replace(/\:\:before/gi, '')}`
              );
            }
          }
        }
      }
      if (iconfonts.length > 0) {
        resolve(iconfonts);
      } else {
        reject('No AwesomeIcon style sheet');
      }
    });
  });
}

引入本地svg圖標(biāo)

在引入本地svg圖標(biāo)之前,我們先了解一下svg標(biāo)簽的相關(guān)知識:

?? 什么是svg?

svg:即 Scalable Vector Graphics,是一種用來繪制矢量圖的 HTML5 標(biāo)簽,與canvas有點類似,它可以像HTML畫布一樣用于制作圖形和動畫。

svg標(biāo)簽常見屬性有:

svg標(biāo)簽內(nèi)部常見的繪制標(biāo)簽有:

  • x: x軸協(xié)調(diào)圖像的位置。
  • y: y軸協(xié)調(diào)圖像的位置。
  • width: 圖像的寬度。
  • height: 圖片的高度。
  • viewBox: SVG元素的界限。
  • id、class屬性
  • fill:svg元素的填充顏色。
  • stroke:svg 元素的描邊顏色,例如線條、文本等描邊顏色。
  • ....
  • <line> 標(biāo)簽:繪制一條直線。
  • <rect> 標(biāo)簽:繪制一個矩形。
  • <polygon> 標(biāo)簽:繪制一個多邊形。
  • <circle> 標(biāo)簽:繪制一個圓形。
  • <ellipse> 標(biāo)簽:繪制一個橢圓。
  • <path> 標(biāo)簽:于繪制路徑,其是 svg 基本形狀中最強大的一個,你可以用它創(chuàng)建線條,曲線,弧形,圓等各種形狀,其具有 d 屬性,用于指定一系列繪制的命令,命令后面接坐標(biāo)。

?? 如何加載svg?

在html中如何定義svg:在svg標(biāo)簽內(nèi)定義繪制圖形的標(biāo)簽。

// 方式一:只能定義一個svg圖標(biāo)
<svg class="hamburger" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="64" height="64">
<path
  d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" />
</svg>
/* 方式二:可定義多個svg圖標(biāo),需要symbol標(biāo)簽配合,把繪制標(biāo)簽定義在symbol標(biāo)簽內(nèi) */
/* 一般是在index.html文件中body標(biāo)簽下定義 */
<svg>
   // 一個symbol定義代表一個圖標(biāo)
   <symbol id="local-vue"></symbol>
   <symbol id="local-logo"></symbol>
   ...
</svg>
/* 然后就可以在組件中實例化使用 */
<svg><use href="#local-vue" rel="external nofollow"  rel="external nofollow" ></use></svg>

?? 封裝加載svg插件?

去掉svg標(biāo)簽,只取svg標(biāo)簽內(nèi)部的繪制內(nèi)容。

let idPrefix = '';
const iconNames: string[] = [];
const svgTitle = /<svg([^>+].*?)>/;
const clearHeightWidth = /(width|height)="([^>+].*?)"/g;// 清空寬高
const hasViewBox = /(viewBox="[^>+].*?")/g;// 是否有ViewBox屬性
const clearReturn = /(\r)|(\n)/g; // 清空換行符
const clearFill = /(fill="[^>+].*?")/g; // 清理 svg 的 fill
// 查找svg所有文件
function findSvgFile(dir: string = '../../../assets/icons/'): string[] {
  const svgRes = [];
  // readdirSync,返回一個包含“指定目錄下所有文件名稱”的數(shù)組對象
  // [ Dirent { name: 'vue.svg', [Symbol(type)]: 1 } ]
  const dirents = readdirSync(dir, {
    withFileTypes: true,
  });
  console.log(dirents);
  for (const dirent of dirents) {
    iconNames.push(`${idPrefix}-${dirent.name.replace('.svg', '')}`); // [ 'local-vue' ]
    // 如果path表示的是一個目錄則返回true
    if (dirent.isDirectory()) {
      svgRes.push(...findSvgFile(dir + dirent.name + '/'));
    } else {
      const svg = readFileSync(dir + dirent.name)
        .toString().replace(clearReturn, '').replace(clearFill, 
        'fill=""'.replace(svgTitle, ($1, $2) => {
          let width = 0;
          let height = 0;
          let content = $2.replace(clearHeightWidth,
            (s1: string, s2: string, s3: number) => {
              if (s2 === 'width') {
                width = s3;
              } else if (s2 === 'height') {
                height = s3;
              }
              return '';
            }
          );
          if (!hasViewBox.test($2)) {
            content += `viewBox="0 0 ${width} ${height}"`;
          }
          // 去掉擴展名
          return `<symbol id="${idPrefix}-${dirent.name.replace(
            '.svg',
            ''
          )}" ${content}>`;
        })
        .replace('</svg>', '</symbol>');// 替換尾部標(biāo)簽
      svgRes.push(svg);
    }
  }
  return svgRes;
}

轉(zhuǎn)化為真正渲染的html,在vite.config中的plugin插件屬性中引入svgBuilder并傳入存放svg圖標(biāo)的路徑。

/**
 *
 * @param path // 所有svg圖標(biāo)存放地址
 * @param perfix // 圖標(biāo)自定義前綴
 * @returns
 */
export const svgBuilder = (path: string, perfix = 'local') => {
  if (path === '') return;
  idPrefix = perfix;
  // 每個圖標(biāo)都是symbol標(biāo)簽,去掉了svg標(biāo)簽,只包含的svg內(nèi)部嵌套標(biāo)簽,res是一個數(shù)組,每個元素就是一個圖標(biāo)
  const res = findSvgFile(path);
  return {
    name: 'svg-transform',
    transformIndexHtml(html: string) {
      /* eslint-disable */
      return html.replace(
        '<body>',
        `
        <body>
        <svg id="local-icon" data-icon-name="${iconNames.join(',')}" 
        xmlns="http://www.w3.org/2000/svg" 
        xmlns:xlink="http://www.w3.org/1999/xlink" 
        style="position: absolute; width: 0; height: 0">
        ${res.join('')}
        </svg>
        `
      );
      /* eslint-enable */
    },
  };
};

獲取所有本地圖標(biāo)名稱通過定義id,由于封裝插件的時候已經(jīng)定義了元素id="local-icon",所以可以全局定義獲取。下面獲取到的svgEl值如圖所示。

export function getLocalIconfontNames() {
  return new Promise<string[]>((resolve, reject) => {
    nextTick(() => {
      let iconfonts: string[] = [];
      const svgEl = document.getElementById('local-icon');
      // 判斷DOMStringMap對象內(nèi)的iconName屬性是否有值
      if (svgEl?.dataset.iconName) {
        iconfonts = (svgEl?.dataset.iconName as string).split(',');
      }
      if (iconfonts.length > 0) {
        resolve(iconfonts);
      } else {
        reject('No Local Icons!');
      }
    });
  });
}

參考資料

以上就是buildAdmin開源項目引入四種圖標(biāo)方式詳解的詳細(xì)內(nèi)容,更多關(guān)于buildAdmin引入圖標(biāo)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解在vue中如何使用node.js

    詳解在vue中如何使用node.js

    這篇文章主要給大家介紹了關(guān)于在vue中如何使用node.js的相關(guān)資料,vue和nodejs經(jīng)常讓新手們感到困惑,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • vue3簡單封裝input組件和統(tǒng)一表單數(shù)據(jù)詳解

    vue3簡單封裝input組件和統(tǒng)一表單數(shù)據(jù)詳解

    最近有一個需求是很多個表單添加,編輯等操作,會用到很多input輸入框,所以就想把input進行簡單封裝,這篇文章主要給大家介紹了關(guān)于vue3簡單封裝input組件和統(tǒng)一表單數(shù)據(jù)的相關(guān)資料,需要的朋友可以參考下
    2022-05-05
  • Vue中的計算屬性和axios基本使用回顧

    Vue中的計算屬性和axios基本使用回顧

    這篇文章主要介紹了Vue中的計算屬性和axios基本使用回顧,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • 詳解在vue-cli項目中安裝node-sass

    詳解在vue-cli項目中安裝node-sass

    本篇文章主要介紹了詳解在vue-cli項目中安裝node-sass ,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • 使用Vue3實現(xiàn)羊了個羊的算法

    使用Vue3實現(xiàn)羊了個羊的算法

    這篇文章主要介紹了使用Vue3實現(xiàn)羊了個羊的算法,初始化的隨機位置算法,通過實例代碼介紹了計算偏移量的方法,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-09-09
  • Vue.js表單控件綁定示例盤點

    Vue.js表單控件綁定示例盤點

    這篇文章主要為大家介紹了一些Vue.js表單控件綁定示例盤點,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • vue與django(drf)實現(xiàn)文件上傳下載功能全過程

    vue與django(drf)實現(xiàn)文件上傳下載功能全過程

    最近簡單的學(xué)習(xí)了django和drf上傳文件(主要是圖片),做一個記錄,下面這篇文章主要給大家介紹了關(guān)于vue與django(drf)實現(xiàn)文件上傳下載功能的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • vue如何重置data的所有屬性

    vue如何重置data的所有屬性

    這篇文章主要介紹了vue如何重置data的所有屬性,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • Vue.js在使用中的一些注意知識點

    Vue.js在使用中的一些注意知識點

    這篇文章主要給大家介紹了Vue.js在使用中的一些注意知識點,文中介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Vue.js具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。
    2017-04-04
  • 詳解vue-router和vue-cli以及組件之間的傳值

    詳解vue-router和vue-cli以及組件之間的傳值

    這篇文章主要介紹了詳解vue-router和vue-cli以及組件之間的傳值,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07

最新評論