tn-tag.vue 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. <template>
  2. <view
  3. class="tn-tag-class tn-tag"
  4. :class="[
  5. tagClass,
  6. backgroundColorClass,
  7. fontColorClass
  8. ]"
  9. :style="[tagStyle]"
  10. @tap="handleClick"
  11. >
  12. <slot></slot>
  13. </view>
  14. </template>
  15. <script>
  16. import componentsColorMixin from '../../libs/mixin/components_color.js'
  17. export default {
  18. mixins: [ componentsColorMixin ],
  19. options: {
  20. // 在微信小程序中将组件节点渲染为虚拟节点,更加接近Vue组件的表现(不会出现shadow节点下再去创建元素)
  21. virtualHost: true
  22. },
  23. name: 'tn-tag',
  24. props: {
  25. // 序号,用于区分多个标签
  26. index: {
  27. type: [Number, String],
  28. default: '0'
  29. },
  30. // 形状 圆角 radius 椭圆 circle 左半圆 circleLeft 右半圆 circleRight
  31. shape: {
  32. type: String,
  33. default: ''
  34. },
  35. // 标签大小 sm lg
  36. size: {
  37. type: String,
  38. default: ''
  39. },
  40. // 宽度
  41. width: {
  42. type: String,
  43. default: ''
  44. },
  45. // 高度
  46. height: {
  47. type: String,
  48. default: ''
  49. },
  50. // 内边距
  51. padding: {
  52. type: String,
  53. default: ''
  54. },
  55. // 外边距
  56. margin: {
  57. type: String,
  58. default: '0'
  59. },
  60. // 是否镂空
  61. plain: {
  62. type: Boolean,
  63. default: false
  64. },
  65. // 是否将元素基点设置在左边
  66. originLeft: {
  67. type: Boolean,
  68. default: false
  69. },
  70. // 是否将元素基点设置在右边
  71. originRight: {
  72. type: Boolean,
  73. default: false
  74. }
  75. },
  76. computed: {
  77. tagClass() {
  78. let clazz = ''
  79. // 设置标签的形状
  80. switch(this.shape) {
  81. case 'radius':
  82. clazz += ' tn-radius'
  83. break
  84. case 'circle':
  85. clazz += ' tn-round'
  86. break
  87. case 'circleLeft':
  88. clazz += ' tn-tag--fillet-left'
  89. break
  90. case 'circleRight':
  91. clazz += ' tn-tag--fillet-right'
  92. break
  93. }
  94. // 设置为镂空并且设置镂空便可才进行设置
  95. if (this.plain) {
  96. clazz += ' tn-tag--plain tn-border-solid'
  97. if (this.backgroundColor !== '' && this.backgroundColor.includes('tn-bg')) {
  98. const color = this.backgroundColor.slice(this.backgroundColor.lastIndexOf('-') + 1)
  99. clazz += ` tn-border-${color}`
  100. }
  101. }
  102. // 设置基准点
  103. if (this.originLeft) {
  104. clazz += ' tn-tag--origin-left'
  105. }
  106. if (this.originRight) {
  107. clazz += ' tn-tag--origin-right'
  108. }
  109. return clazz
  110. },
  111. tagStyle() {
  112. let style = {}
  113. switch(this.size) {
  114. case 'sm':
  115. style.padding = '0 12rpx'
  116. style.fontSize = '20rpx'
  117. style.height = '32rpx'
  118. break
  119. case 'lg':
  120. style.padding = '0 20rpx'
  121. style.fontSize = '28rpx'
  122. style.height = '62rpx'
  123. break
  124. default:
  125. style.padding = '0 16rpx'
  126. style.fontSize = '24rpx'
  127. style.height = '48rpx'
  128. break
  129. }
  130. style.width = this.width || 'auto'
  131. style.height = this.height || style.height
  132. style.padding = this.padding || style.padding
  133. if (this.margin) {
  134. style.margin = this.margin
  135. }
  136. if (this.fontColorStyle) {
  137. style.color = this.fontColorStyle
  138. }
  139. if (this.fontSize !== 0) {
  140. style.fontSize = this.fontSize + this.fontUnit
  141. }
  142. if (!this.backgroundColorClass) {
  143. style.backgroundColor = !this.plain ? (this.backgroundColorStyle || '#FFFFFF') : ''
  144. if (this.plain) {
  145. style.borderColor = (this.backgroundColorStyle || '#080808')
  146. }
  147. }
  148. return style
  149. },
  150. },
  151. data() {
  152. return {
  153. }
  154. },
  155. methods: {
  156. // 处理点击事件
  157. handleClick() {
  158. this.$emit('click', {
  159. index: Number(this.index)
  160. })
  161. this.$emit('tap', {
  162. index: Number(this.index)
  163. })
  164. },
  165. }
  166. }
  167. </script>
  168. <style lang="scss" scoped>
  169. .tn-tag {
  170. vertical-align: middle;
  171. position: relative;
  172. display: inline-flex;
  173. align-items: center;
  174. justify-content: center;
  175. box-sizing: border-box;
  176. font-family: Helvetica Neue, Helvetica, sans-serif;
  177. white-space: nowrap;
  178. // color: #FFFFFF;
  179. &--fillet-left {
  180. border-radius: 50rpx 0 0 50rpx;
  181. }
  182. &--fillet-right {
  183. border-radius: 0 50rpx 50rpx 0;
  184. }
  185. &--plain {
  186. background-color: transparent !important;
  187. background-image: none;
  188. &.tn-round {
  189. border-radius: 1000rpx !important;
  190. }
  191. &.tn-radius {
  192. border-radius: 12rpx !important;
  193. }
  194. }
  195. &--origin-left {
  196. transform-origin: 0 center;
  197. }
  198. &--origin-right {
  199. transform-origin: 100% center;
  200. }
  201. }
  202. </style>