🧑🎓 个人主页:SilenceLamb
📖 本章内容:【自定义Icon图标】
Silence-Vue v1.0.0
基于VUE前端快速开发框架
🍎平台简介
一、自定义Icon图标
npm install --save svg-sprite-loader
1.1🌳创建SvgIcon组件
- 🌳 创建SvgIcon组件:src/components/SvgIcon/index.vue
<template>
<div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" />
<svg v-else :class="svgClass" aria-hidden="true">
<use :xlink:href="iconName" />
</svg>
</template>
- 🌳 接收传来的值:src/components/SvgIcon/index.vue
<script>
import { isExternal } from '@/utils/tool/validate'
export default {
name: 'SvgIcon',
props: {
iconClass: {
type: String,
required: true
},
className: {
type: String,
default: ''
}
},
//计算属性
computed: {}
}
</script>
- 🌳 计算属性:src/components/SvgIcon/index.vue
//计算属性
computed: {
/**
* 判断是否是外部Icon图标
* @return true/false
*/
isExternal() {
return isExternal(this.iconClass)
},
/**
* 构建Icon名字
* @return #icon-password
*/
iconName() {
return `#icon-${this.iconClass}`
},
/**
* 构建Icon样式
* @return svg-icon+[classname]
*/
svgClass() {
if (this.className) {
return 'svg-icon ' + this.className
} else {
return 'svg-icon'
}
},
styleExternalIcon() {
return {
mask: `url(${this.iconClass}) no-repeat 50% 50%`,
'-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
}
}
}
- 🌳 样式编写:src/components/SvgIcon/index.vue
<style lang="less" scoped>
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
.svg-external-icon {
background-color: currentColor;
mask-size: cover !important;
display: inline-block;
}
</style>
1.2🌳是否为外部图标
- 🌳判断是否为外部图标:src/utils/tools/validate/index.js
/**
* 判断是否是外部图标
* @param {string} path
* @returns {Boolean}
*/
export function isExternal(path) {
return /^(https?:|mailto:|tel:)/.test(path)
}
1.3🌳在文件中查找图标
- ⏰ webpack 中是使用 require.context() 来查找文件内容的
- ⏰ 在文件中查找图标:index.js
//webpack 中是使用 require.context() 来查找文件内容的
const req = require.context('./svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys().map(requireContext)
requireAll(req)
1.4🌳全局注册Icon组件
- 🌟全局注册组件:src/icons/index.js
/**
* Icon图标注册
* @description: 自定义Icon图标
* @description: ElementPlus-Icon图标
*/
import SvgIcon from '@/components/SvgIcon/index'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
const req = require.context('./svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys().map(requireContext)
requireAll(req)
export default (app) => {
/*自定义Icon图标*/
app.component('svg-icon', SvgIcon)
/*elementPlus-Icon*/
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
}
- 🌟 svg图标格式:src/main.js
import {createApp} from 'vue'
import App from './App.vue'
import SvgIcon from '@/icons/index' // 引入SVG图标
const app = createApp(App)
SvgIcon(app)
app.mount('#app')
- 🌟 svg图标:src/icons/svg/404.svg
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M121.718 73.272v9.953c3.957-7.584 6.199-16.05 6.199-24.995C127.917 26.079 99.273 0 63.958 0 28.644 0 0 26.079 0 58.23c0 .403.028.806.028 1.21l22.97-25.953h13.34l-19.76 27.187h6.42V53.77l13.728-19.477v49.361H22.998V73.272H2.158c5.951 20.284 23.608 36.208 45.998 41.399-1.44 3.3-5.618 11.263-12.565 12.674-8.607 1.764 23.358.428 46.163-13.178 17.519-4.611 31.938-15.849 39.77-30.513h-13.506V73.272H85.02V59.464l22.998-25.977h13.008l-19.429 27.187h6.421v-7.433l13.727-19.402v39.433h-.027zm-78.24 2.822a10.516 10.516 0 0 1-.996-4.535V44.548c0-1.613.332-3.124.996-4.535a11.66 11.66 0 0 1 2.713-3.68c1.134-1.032 2.49-1.864 4.04-2.468 1.55-.605 3.21-.908 4.982-.908h11.292c1.77 0 3.431.303 4.981.908 1.522.604 2.85 1.41 3.986 2.418l-12.26 16.303v-2.898a1.96 1.96 0 0 0-.665-1.512c-.443-.403-.996-.604-1.66-.604-.665 0-1.218.201-1.661.604a1.96 1.96 0 0 0-.664 1.512v9.071L44.364 77.606a10.556 10.556 0 0 1-.886-1.512zm35.73-4.535c0 1.613-.332 3.124-.997 4.535a11.66 11.66 0 0 1-2.712 3.68c-1.134 1.032-2.49 1.864-4.04 2.469-1.55.604-3.21.907-4.982.907H55.185c-1.77 0-3.431-.303-4.981-.907-1.55-.605-2.906-1.437-4.041-2.47a12.49 12.49 0 0 1-1.384-1.512l13.727-18.217v6.375c0 .605.222 1.109.665 1.512.442.403.996.604 1.66.604.664 0 1.218-.201 1.66-.604a1.96 1.96 0 0 0 .665-1.512V53.87L75.97 36.838c.913.932 1.66 1.99 2.214 3.175.664 1.41.996 2.922.996 4.535v27.011h.028z"/></svg>
- 🌟使用Icon图标:index.vue
<span class="svg-container">
<svg-icon icon-class="user" />
</span>
1.5🌳将图标进行打包
- 🤾🏻♀️ 将图标进行打包:vue.config.js
chainWebpack(config) {
// set svg-sprite-loader
config.module
.rule('svg')
.exclude.add(resolve('src/icons'))
.end()
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('src/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()
}
二、复制文本功能
- ☃️ 安装clipboard
npm install --save clipboard
import Clipboard from 'clipboard'
import model from '@/utils/plugins/modules/message'
function clipboardSuccess() {
model.notifySuccess("Copy success")
}
function clipboardError(){
model.notifyError("Copy failed")
}
export default function handleClipboard(text, event) {
const clipboard = new Clipboard(event.target, {
text: () => text
})
clipboard.on('success', () => {
clipboardSuccess()
clipboard.destroy()
})
clipboard.on('error', () => {
clipboardError()
clipboard.destroy()
})
clipboard.onClick(event)
}