mangosteen day 6 封装icon

写代码的时候一定要注意一个
组件化的思想
我们封装一个icon组件 可以使得我们后面的代码变得精简(这样我们就不用单独的给每一个新添加的svg添加样式)

先一个svgsprites(类似于自制的vite插件)

import path from 'path'
import fs from 'fs'
import store from 'svgstore'
import { optimize } from 'svgo'
import type { Plugin, ViteDevServer } from 'vite'

interface Options {
  id?: string
  inputFolder?: string
  inline?: boolean
}
export const svgsprites = (options: Options = {}): Plugin => {
  const virtualModuleId = `virtual:svgsprites${options.id ? `-${options.id}` : ''}`
  const resolvedVirtualModuleId = `\0${virtualModuleId}`
  const { inputFolder = 'src/assets/icons', inline = false } = options

  const generateCode = () => {
    const sprites = store(options)
    const iconsDir = path.resolve(inputFolder)
    for (const file of fs.readdirSync(iconsDir)) {
      if (!file.endsWith('.svg')) { continue }
      const filepath = path.join(iconsDir, file)
      const svgId = path.parse(file).name
      const code = fs.readFileSync(filepath, { encoding: 'utf-8' })
      sprites.add(svgId, code)
    }
    const { data: code } = optimize(sprites.toString({ inline }), {
      plugins: [
        'cleanupAttrs', 'removeDoctype', 'removeComments', 'removeTitle', 'removeDesc', 'removeEmptyAttrs',
        { name: 'removeAttrs', params: { attrs: '(data-name|fill)' } },
      ],
    })
    return code
  }
  const handleFileCreationOrUpdate = (file: string, server: ViteDevServer) => {
    if (!file.includes(inputFolder)) { return }
    const code = generateCode()
    server.ws.send('svgsprites:change', { code })
    const mod = server.moduleGraph.getModuleById(resolvedVirtualModuleId)
    if (!mod) { return }
    server.moduleGraph.invalidateModule(mod, undefined, Date.now())
  }

  return {
    name: 'svgsprites',
    configureServer(server) {
      server.watcher.on('add', (file) => {
        handleFileCreationOrUpdate(file, server)
      })
      server.watcher.on('change', (file) => {
        handleFileCreationOrUpdate(file, server)
      })
    },
    resolveId(id: string) {
      if (id === virtualModuleId) {
        return resolvedVirtualModuleId
      }
    },
    load(id: string) {
      if (id === resolvedVirtualModuleId) {
        const code = generateCode()
        return `!function(){
  const div = document.createElement('div')
  div.innerHTML = \`${code}\`
  const svg = div.getElementsByTagName('svg')[0]
  const updateSvg = (svg) => {
    if (!svg) { return }
    svg.style.position = 'absolute'
    svg.style.width = 0
    svg.style.height = 0
    svg.style.overflow = 'hidden'
    svg.setAttribute("aria-hidden", "true")
  }
  const insert = () => {
    if (document.body.firstChild) {
      document.body.insertBefore(div, document.body.firstChild)
    } else {
      document.body.appendChild(div)
    }
  }
  updateSvg(svg)
  if (document.body){
    insert()
  } else {
    document.addEventListener('DOMContentLoaded', insert)
  }
  if (import.meta.hot) {
    import.meta.hot.on('svgsprites:change', (data) => {
      const code = data.code
      div.innerHTML = code
      const svg = div.getElementsByTagName('svg')[0]
      updateSvg(svg)
    })
  }
}()`
      }
    },
  }
}






然后我们就可以将组件icon函数用来每次引入svg

import c from 'classnames'  //引入classnames库 可以同时引入两个classname
interface Props{
    className:string,
    name: string
}//说明类型 引入两个参数
export const Icon:React.FC<Props> = ({name,className}) =>{
 return <svg className={c(className , 'q-icon')} >
 <use xlinkHref={`#${name}`} ></use>  
</svg>
};
//q-icon是给的一个默认的icon的样式 由下面用layer层级来调整优先级
//这样方便我们后面覆盖新的样式 xlinkHref是引入svg







当我们创建组建的时候,遇到 ‘新的样式无法替代’ 这个问题的时候 就需要改变CSS的层级

我们可以使用 preflightlayer 改变 CSS 顺序

方法就是可以直接在uno.config这个文件使用preflights


  preflights: [
    {
      layer:  'components',
      getCSS: ({ theme }) => `   
      .q-icon{
        fill:currentColor;
        width: 1.2em;
        height: 1.2em;
    }
      
    `
}], //引号里面直接要写上原先需要被覆盖的原始样式 其原理就是利用不同的layer的优先层级不同 components: -1,default: 1,utilities: 2, 让我们原始的样式的优先级最低 这样我们就可以很容易的覆盖

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容