u-tag.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. <template>
  2. <u-transition mode="fade" :show="show">
  3. <view class="u-tag-wrapper">
  4. <view class="u-tag"
  5. :class="[`u-tag--${shape}`, !plain && `u-tag--${type}`, plain && `u-tag--${type}--plain`, `u-tag--${size}`, plain && plainFill && `u-tag--${type}--plain--fill`]"
  6. @tap.stop="clickHandler" :style="[{
  7. marginRight: closable ? '10px' : 0,
  8. marginTop: closable ? '10px' : 0,
  9. }, style]">
  10. <slot name="icon">
  11. <view class="u-tag__icon" v-if="icon">
  12. <image v-if="$u.test.image(icon)" :src="icon" :style="[imgStyle]"></image>
  13. <u-icon v-else :color="elIconColor" :name="icon" :size="iconSize"></u-icon>
  14. </view>
  15. </slot>
  16. <text class="u-tag__text" :style="[textColor]"
  17. :class="[`u-tag__text--${type}`, plain && `u-tag__text--${type}--plain`, `u-tag__text--${size}`]">{{ text }}</text>
  18. </view>
  19. <view class="u-tag__close" :class="[`u-tag__close--${size}`]" v-if="closable" @tap.stop="closeHandler"
  20. :style="{backgroundColor: closeColor}">
  21. <u-icon name="close" :size="closeSize" color="#ffffff"></u-icon>
  22. </view>
  23. </view>
  24. </u-transition>
  25. </template>
  26. <script>
  27. import props from './props.js';
  28. /**
  29. * Tag 标签
  30. * @description tag组件一般用于标记和选择,我们提供了更加丰富的表现形式,能够较全面的涵盖您的使用场景
  31. * @tutorial https://www.uviewui.com/components/tag.html
  32. * @property {String} type 标签类型info、primary、success、warning、error (默认 'primary' )
  33. * @property {Boolean | String} disabled 不可用(默认 false )
  34. * @property {String} size 标签的大小,large,medium,mini (默认 'medium' )
  35. * @property {String} shape tag的形状,circle(两边半圆形), square(方形,带圆角)(默认 'square' )
  36. * @property {String | Number} text 标签的文字内容
  37. * @property {String} bgColor 背景颜色,默认为空字符串,即不处理
  38. * @property {String} color 标签字体颜色,默认为空字符串,即不处理
  39. * @property {String} borderColor 镂空形式标签的边框颜色
  40. * @property {String} closeColor 关闭按钮图标的颜色(默认 #C6C7CB)
  41. * @property {String | Number} name 点击时返回的索引值,用于区分例遍的数组哪个元素被点击了
  42. * @property {Boolean} plainFill 镂空时是否填充背景色(默认 false )
  43. * @property {Boolean} plain 是否镂空(默认 false )
  44. * @property {Boolean} closable 是否可关闭,设置为true,文字右边会出现一个关闭图标(默认 false )
  45. * @property {Boolean} show 标签显示与否(默认 true )
  46. * @property {String} icon 内置图标,或绝对路径的图片
  47. * @event {Function(index)} click 点击标签时触发 index: 传递的index参数值
  48. * @event {Function(index)} close closable为true时,点击标签关闭按钮触发 index: 传递的index参数值
  49. * @example <u-tag text="标签" type="error" plain plainFill></u-tag>
  50. */
  51. export default {
  52. name: 'u-tag',
  53. mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
  54. data() {
  55. return {
  56. }
  57. },
  58. computed: {
  59. style() {
  60. const style = {}
  61. if (this.bgColor) {
  62. style.backgroundColor = this.bgColor
  63. }
  64. if (this.color) {
  65. style.color = this.color
  66. }
  67. if (this.borderColor) {
  68. style.borderColor = this.borderColor
  69. }
  70. return style
  71. },
  72. // nvue下,文本颜色无法继承父元素
  73. textColor() {
  74. const style = {}
  75. if (this.color) {
  76. style.color = this.color
  77. }
  78. return style
  79. },
  80. imgStyle() {
  81. const width = this.size === 'large' ? '17px' : this.size === 'medium' ? '15px' : '13px'
  82. return {
  83. width,
  84. height: width
  85. }
  86. },
  87. // 文本的样式
  88. closeSize() {
  89. const size = this.size === 'large' ? 15 : this.size === 'medium' ? 13 : 12
  90. return size
  91. },
  92. // 图标大小
  93. iconSize() {
  94. const size = this.size === 'large' ? 21 : this.size === 'medium' ? 19 : 16
  95. return size
  96. },
  97. // 图标颜色
  98. elIconColor() {
  99. return this.iconColor ? this.iconColor : this.plain ? this.type : '#ffffff'
  100. }
  101. },
  102. methods: {
  103. // 点击关闭按钮
  104. closeHandler() {
  105. this.$emit('close', this.name)
  106. },
  107. // 点击标签
  108. clickHandler() {
  109. this.$emit('click', this.name)
  110. }
  111. }
  112. }
  113. </script>
  114. <style lang="scss" scoped>
  115. @import "../../libs/css/components.scss";
  116. .u-tag-wrapper {
  117. position: relative;
  118. width: fit-content;
  119. margin-right: 10px;
  120. }
  121. .u-tag {
  122. @include flex;
  123. align-items: center;
  124. border-style: solid;
  125. width: auto;
  126. &--circle {
  127. border-radius: 100px;
  128. }
  129. &--square {
  130. border-radius: 3px;
  131. }
  132. &__icon {
  133. margin-right: 4px;
  134. }
  135. &__text {
  136. &--mini {
  137. font-size: 12px;
  138. line-height: 12px;
  139. }
  140. &--medium {
  141. font-size: 13px;
  142. line-height: 13px;
  143. }
  144. &--large {
  145. font-size: 15px;
  146. line-height: 15px;
  147. }
  148. }
  149. &--mini {
  150. height: 22px;
  151. line-height: 22px;
  152. padding: 0 5px;
  153. }
  154. &--medium {
  155. height: 26px;
  156. line-height: 22px;
  157. padding: 0 10px;
  158. }
  159. &--large {
  160. height: 32px;
  161. line-height: 32px;
  162. padding: 0 15px;
  163. }
  164. &--primary {
  165. background-color: $u-primary;
  166. border-width: 1px;
  167. border-color: $u-primary;
  168. }
  169. &--primary--plain {
  170. border-width: 1px;
  171. border-color: $u-primary;
  172. }
  173. &--primary--plain--fill {
  174. background-color: #ecf5ff;
  175. }
  176. &__text--primary {
  177. color: #FFFFFF;
  178. }
  179. &__text--primary--plain {
  180. color: $u-primary;
  181. }
  182. &--error {
  183. background-color: $u-error;
  184. border-width: 1px;
  185. border-color: $u-error;
  186. }
  187. &--error--plain {
  188. border-width: 1px;
  189. border-color: $u-error;
  190. }
  191. &--error--plain--fill {
  192. background-color: #fef0f0;
  193. }
  194. &__text--error {
  195. color: #FFFFFF;
  196. }
  197. &__text--error--plain {
  198. color: $u-error;
  199. }
  200. &--warning {
  201. background-color: $u-warning;
  202. border-width: 1px;
  203. border-color: $u-warning;
  204. }
  205. &--warning--plain {
  206. border-width: 1px;
  207. border-color: $u-warning;
  208. }
  209. &--warning--plain--fill {
  210. background-color: #fdf6ec;
  211. }
  212. &__text--warning {
  213. color: #FFFFFF;
  214. }
  215. &__text--warning--plain {
  216. color: $u-warning;
  217. }
  218. &--success {
  219. background-color: $u-success;
  220. border-width: 1px;
  221. border-color: $u-success;
  222. }
  223. &--success--plain {
  224. border-width: 1px;
  225. border-color: $u-success;
  226. }
  227. &--success--plain--fill {
  228. background-color: #f5fff0;
  229. }
  230. &__text--success {
  231. color: #FFFFFF;
  232. }
  233. &__text--success--plain {
  234. color: $u-success;
  235. }
  236. &--info {
  237. background-color: $u-info;
  238. border-width: 1px;
  239. border-color: $u-info;
  240. }
  241. &--info--plain {
  242. border-width: 1px;
  243. border-color: $u-info;
  244. }
  245. &--info--plain--fill {
  246. background-color: #f4f4f5;
  247. }
  248. &__text--info {
  249. color: #FFFFFF;
  250. }
  251. &__text--info--plain {
  252. color: $u-info;
  253. }
  254. &__close {
  255. position: absolute;
  256. z-index: 999;
  257. top: 10px;
  258. right: 10px;
  259. border-radius: 100px;
  260. background-color: #C6C7CB;
  261. @include flex(row);
  262. align-items: center;
  263. justify-content: center;
  264. /* #ifndef APP-NVUE */
  265. transform: scale(0.6) translate(80%, -80%);
  266. /* #endif */
  267. /* #ifdef APP-NVUE */
  268. transform: scale(0.6) translate(50%, -50%);
  269. /* #endif */
  270. &--mini {
  271. width: 18px;
  272. height: 18px;
  273. }
  274. &--medium {
  275. width: 22px;
  276. height: 22px;
  277. }
  278. &--large {
  279. width: 25px;
  280. height: 25px;
  281. }
  282. }
  283. }
  284. </style>