前言
项目开发环境uni-app,H5可以更换<text>成<i>即可。
iconfont 图标及入门姿势可以参考这篇文章iconfont+
创建Icon组件
我们有自己iconfont图标后,接下来就可以在的项目创建一个icon组件使用这些iconfont图标了。
没有封装前,使用icon大概长这样
<text class="crab crab-gou" style="font-size: 28rpx; color: #333;">
显然太过于麻烦,封装组件后,大概长这样,遇到需要动态修改的地方更加方便。
<ca-icon name="crab-gou" size="28" color:"#333" />
大概的思路
- 引入
iconfont图标样式 - 在传入大小名称和样式
<template>
<text
@tap.stop="handleClick"
class="ca-icon"
:class="[classPrefix_, name]"
:style="[iconStyle_]"
></text>
</template>
<script>
import { defineComponent, toRefs, computed } from 'vue'
export default defineComponent({
props: {
name: {
type: String,
default: '',
},
size: {
type: [String, Number],
default: '28',
},
color: {
type: [String, Boolean],
default: 'inherit',
},
size: {
type: [Number, String],
default: 28,
},
},
setup(props, { emit }) {
const handleClick = (e) => {
emit('click', e)
}
const iconStyle_ = computed(() => {
// 组件样式
const obj = {
fontSize: String(props.size).indexOf('px') !== -1 ? props.size : uni.upx2px(props.size) + 'px',
}
// icon名称
const classPrefix_ = computed(() => {
const prevName = props.name.split('-')[0]
const name = prevName === 'icon' ? 'iconfont' : prevName
return name
})
String(props.color) !== 'false' && (obj['color'] = props.color)
return obj
})
return {
iconStyle_,
classPrefix_,
handleClick,
...toRefs(props),
}
},
})
</script>
<style lang="scss" scoped>
@import './font.css';
.ca-icon {
font-size: 0;
@include tst(transform);
vertical-align: middle;
position: relative;
display: inline-block;
font-size: inherit;
// 浏览器渲染引擎如何渲染字体。浏览器会在速度、清晰度、几何精度之间进行权衡。
text-rendering: auto;
-webkit-font-smoothing: antialiased;
}
</style>
嗯 一个简单的icon 组件封装好了。
Vant中功能都有了,除了小点点,不想写,就是玩,觉得用处不大。
进一步改造
阿就这,就这样完了嘛?
在实际的项目开发中,一起开发的同事有提了新的需求。
- 要是图标可以旋转,一直转圈,转圈速度自己调节。
- 要是图标可以旋转一定的角度。
就更好了,行吧,安排
于是乎在原来的基础上添加几行代码,如下
<template>
<text
@tap.stop="handleClick"
class="ca-icon"
:class="[classPrefix_, name]"
:style="[iconStyle_]"
></text>
</template>
<script >
import { defineComponent, toRefs, computed } from 'vue'
export default defineComponent({
props: {
name: {
type: String,
default: '',
},
size: {
type: [String, Number],
default: '28',
},
color: {
type: [String, Boolean],
default: 'inherit',
},
size: {
type: [Number, String],
default: 28,
},
spin: {
type: Boolean,
default: false,
},
spinGap: {
type: [Number, String],
default: 1.5,
},
rotate: {
type: [Number, String, Boolean],
default: false,
},
},
setup(props, { emit }) {
const handleClick = (e) => {
emit('click', e)
}
const rotate_ = computed(() => {
return String(props.rotate) === 'false' ? false : props.rotate
})
// class-prefix
const classPrefix_ = computed(() => {
const prevName = props.name.split('-')[0]
const name = prevName === 'icon' ? 'iconfont' : prevName
return name
})
const iconStyle_ = computed(() => {
// 组件样式
const obj = {
fontSize:
String(props.size).indexOf('px') !== -1
? props.size
: uni.upx2px(props.size) + 'px',
}
String(props.color) !== 'false' && (obj['color'] = props.color)
// 组件动画
rotate_.value &&
(obj.transform = isNaN(props.rotate)
? `rotate(${props.rotate})`
: `rotate(${props.rotate}deg)`)
if (props.spin) {
obj.animation = `ca-spin ${props.spinGap}s linear infinite`
}
return obj
})
return {
iconStyle_,
classPrefix_,
handleClick,
...toRefs(props),
}
},
})
</script>
<style lang="scss" scoped>
@import './font.css';
.ca-icon {
font-size: 0;
@include tst(transform);
vertical-align: middle;
position: relative;
display: inline-block;
font-size: inherit;
// 浏览器渲染引擎如何渲染字体。浏览器会在速度、清晰度、几何精度之间进行权衡。
text-rendering: auto;
-webkit-font-smoothing: antialiased;
}
</style>
scss 动画
// 旋转动画
@keyframes ca-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
效果
// 在代码中使用
<view class="p-30"> icon </view>
<ca-icon name="crab-gou" />
<ca-icon name="crab-modal" color="#888" />
<ca-icon name="crab-shijian1" size="60" />
<ca-icon name="crab-aixin1" rotate="45" />
<ca-icon name="crab-shoucang1" spin />
<ca-icon name="crab-shoucang1" spin spinGap="5" />
如图所示