u-icon.vue 7.15 KB
Newer Older
潘永坪's avatar
潘永坪 committed
1
<template>
潘永坪's avatar
潘永坪 committed
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
	<view
	    class="u-icon"
	    @tap="clickHandler"
	    :class="['u-icon--' + labelPos]"
	>
		<image
		    class="u-icon__img"
		    v-if="isImg"
		    :src="name"
		    :mode="imgMode"
		    :style="[imgStyle, $u.addStyle(customStyle)]"
		></image>
		<text
		    v-else
		    class="u-icon__icon"
		    :class="uClasses"
		    :style="[iconStyle, $u.addStyle(customStyle)]"
		    :hover-class="hoverClass"
		>{{icon}}</text>
潘永坪's avatar
潘永坪 committed
21
		<!-- 这里进行空字符串判断,如果仅仅是v-if="label",可能会出现传递0的时候,结果也无法显示 -->
潘永坪's avatar
潘永坪 committed
22 23 24 25
		<text
		    v-if="label !== ''" 
		    class="u-icon__label"
		    :style="{
潘永坪's avatar
潘永坪 committed
26 27
			color: labelColor,
			fontSize: $u.addUnit(labelSize),
潘永坪's avatar
潘永坪 committed
28 29 30 31 32 33
			marginLeft: labelPos == 'right' ? $u.addUnit(space) : 0,
			marginTop: labelPos == 'bottom' ? $u.addUnit(space) : 0,
			marginRight: labelPos == 'left' ? $u.addUnit(space) : 0,
			marginBottom: labelPos == 'top' ? $u.addUnit(space) : 0,
		}"
		>{{ label }}</text>
潘永坪's avatar
潘永坪 committed
34 35 36 37
	</view>
</template>

<script>
潘永坪's avatar
潘永坪 committed
38 39 40 41 42 43 44 45 46 47 48 49 50
// #ifdef APP-NVUE
// nvue通过weex的dom模块引入字体,相关文档地址如下:
// https://weex.apache.org/zh/docs/modules/dom.html#addrule
const fontUrl = 'https://at.alicdn.com/t/font_2225171_8kdcwk4po24.ttf'
const domModule = weex.requireModule('dom')
domModule.addRule('fontFace', {
  'fontFamily': 'uicon-iconfont',
  'src': `url('${fontUrl}')`
})
// #endif

// 引入图标名称,已经对应的unicode
import icons from './icons'
潘永坪's avatar
潘永坪 committed
51
	
潘永坪's avatar
潘永坪 committed
52
import props from './props.js'
潘永坪's avatar
潘永坪 committed
53

潘永坪's avatar
潘永坪 committed
54
/**
潘永坪's avatar
潘永坪 committed
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
	 * icon 图标
	 * @description 基于字体的图标集,包含了大多数常见场景的图标。
	 * @tutorial https://www.uviewui.com/components/icon.html
	 * @property {String}			name			图标名称,见示例图标集
	 * @property {String}			color			图标颜色,可接受主题色 (默认 color['u-content-color'] )
	 * @property {String | Number}	size			图标字体大小,单位px (默认 '16px' )
	 * @property {Boolean}			bold			是否显示粗体 (默认 false )
	 * @property {String | Number}	index			点击图标的时候传递事件出去的index(用于区分点击了哪一个)
	 * @property {String}			hoverClass		图标按下去的样式类,用法同uni的view组件的hoverClass参数,详情见官网
	 * @property {String}			customPrefix	自定义扩展前缀,方便用户扩展自己的图标库 (默认 'uicon' )
	 * @property {String | Number}	label			图标右侧的label文字
	 * @property {String}			labelPos		label相对于图标的位置,只能right或bottom (默认 'right' )
	 * @property {String | Number}	labelSize		label字体大小,单位px (默认 '15px' )
	 * @property {String}			labelColor		图标右侧的label文字颜色 ( 默认 color['u-content-color'] )
	 * @property {String | Number}	space			label与图标的距离,单位px (默认 '3px' )
	 * @property {String}			imgMode			图片的mode
	 * @property {String | Number}	width			显示图片小图标时的宽度
	 * @property {String | Number}	height			显示图片小图标时的高度
	 * @property {String | Number}	top				图标在垂直方向上的定位 用于解决某些情况下,让图标垂直居中的用途  (默认 0 )
	 * @property {Boolean}			stop			是否阻止事件传播 (默认 false )
	 * @property {Object}			customStyle		icon的样式,对象形式
	 * @event {Function} click 点击图标时触发
	 * @event {Function} touchstart 事件触摸时触发
	 * @example <u-icon name="photo" color="#2979ff" size="28"></u-icon>
	 */
潘永坪's avatar
潘永坪 committed
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
export default {
  name: 'u-icon',
  data() {
    return {

    }
  },
  mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
  computed: {
    uClasses() {
      let classes = []
      classes.push(this.customPrefix + '-' + this.name)
      // // uView的自定义图标类名为u-iconfont
      // if (this.customPrefix == 'uicon') {
      // 	classes.push('u-iconfont')
      // } else {
      // 	classes.push(this.customPrefix)
      // }
      // 主题色,通过类配置
      if (this.color && uni.$u.config.type.includes(this.color)) classes.push('u-icon__icon--' + this.color)
      // 阿里,头条,百度小程序通过数组绑定类名时,无法直接使用[a, b, c]的形式,否则无法识别
      // 故需将其拆成一个字符串的形式,通过空格隔开各个类名
      //#ifdef MP-ALIPAY || MP-TOUTIAO || MP-BAIDU
      classes = classes.join(' ')
      //#endif
      return classes
    },
    iconStyle() {
      let style = {}
      style = {
        fontSize: uni.$u.addUnit(this.size),
        lineHeight: uni.$u.addUnit(this.size),
        fontWeight: this.bold ? 'bold' : 'normal',
        // 某些特殊情况需要设置一个到顶部的距离,才能更好的垂直居中
        top: uni.$u.addUnit(this.top)
      }
      // 非主题色值时,才当作颜色值
      if (this.color && !uni.$u.config.type.includes(this.color)) style.color = this.color

      return style
    },
    // 判断传入的name属性,是否图片路径,只要带有"/"均认为是图片形式
    isImg() {
      return this.name.indexOf('/') !== -1
    },
    imgStyle() {
      let style = {}
      // 如果设置width和height属性,则优先使用,否则使用size属性
      style.width = this.width ? uni.$u.addUnit(this.width) : uni.$u.addUnit(this.size)
      style.height = this.height ? uni.$u.addUnit(this.height) : uni.$u.addUnit(this.size)
      return style
    },
    // 通过图标名,查找对应的图标
    icon() {
      // 如果内置的图标中找不到对应的图标,就直接返回name值,因为用户可能传入的是unicode代码
      return icons['uicon-' + this.name] || this.name
    }
  },
  methods: {
    clickHandler(e) {
      this.$emit('click', this.index)
      // 是否阻止事件冒泡
      this.stop && this.preventEvent(e)
    }
  }
}
潘永坪's avatar
潘永坪 committed
146 147
</script>

潘永坪's avatar
潘永坪 committed
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
<style lang="scss" scoped>
	@import "../../libs/css/components.scss";

	// 变量定义
	$u-icon-primary: $u-primary !default;
	$u-icon-success: $u-success !default;
	$u-icon-info: $u-info !default;
	$u-icon-warning: $u-warning !default;
	$u-icon-error: $u-error !default;
	$u-icon-label-line-height:1 !default;

	/* #ifndef APP-NVUE */
	// 非nvue下加载字体
	@font-face {
		font-family: 'uicon-iconfont';
		src: url('https://at.alicdn.com/t/font_2225171_8kdcwk4po24.ttf') format('truetype');
潘永坪's avatar
潘永坪 committed
164
	}
潘永坪's avatar
潘永坪 committed
165
	/* #endif */
潘永坪's avatar
潘永坪 committed
166

潘永坪's avatar
潘永坪 committed
167 168 169 170 171
	.u-icon {
		/* #ifndef APP-NVUE */
		display: flex;
		/* #endif */
		align-items: center;
潘永坪's avatar
潘永坪 committed
172

潘永坪's avatar
潘永坪 committed
173 174 175
		&--left {
			flex-direction: row-reverse;
			align-items: center;
潘永坪's avatar
潘永坪 committed
176 177
		}

潘永坪's avatar
潘永坪 committed
178 179 180
		&--right {
			flex-direction: row;
			align-items: center;
潘永坪's avatar
潘永坪 committed
181 182
		}

潘永坪's avatar
潘永坪 committed
183 184 185
		&--top {
			flex-direction: column-reverse;
			justify-content: center;
潘永坪's avatar
潘永坪 committed
186 187
		}

潘永坪's avatar
潘永坪 committed
188 189 190
		&--bottom {
			flex-direction: column;
			justify-content: center;
潘永坪's avatar
潘永坪 committed
191 192
		}

潘永坪's avatar
潘永坪 committed
193 194 195 196 197
		&__icon {
			font-family: uicon-iconfont;
			position: relative;
			@include flex;
			align-items: center;
潘永坪's avatar
潘永坪 committed
198

潘永坪's avatar
潘永坪 committed
199 200 201
			&--primary {
				color: $u-icon-primary;
			}
潘永坪's avatar
潘永坪 committed
202

潘永坪's avatar
潘永坪 committed
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
			&--success {
				color: $u-icon-success;
			}

			&--error {
				color: $u-icon-error;
			}

			&--warning {
				color: $u-icon-warning;
			}

			&--info {
				color: $u-icon-info;
			}
		}
潘永坪's avatar
潘永坪 committed
219

潘永坪's avatar
潘永坪 committed
220 221 222 223 224 225 226 227 228 229 230 231
		&__img {
			/* #ifndef APP-NVUE */
			height: auto;
			will-change: transform;
			/* #endif */
		}

		&__label {
			/* #ifndef APP-NVUE */
			line-height: $u-icon-label-line-height;
			/* #endif */
		}
潘永坪's avatar
潘永坪 committed
232 233
	}
</style>