uni-badge.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. <template>
  2. <view class="uni-badge--x">
  3. <slot />
  4. <text v-if="text" :class="classNames" :style="[badgeWidth, positionStyle, customStyle, dotStyle]"
  5. class="uni-badge"
  6. @click="onClick()">{{displayValue}}</text>
  7. </view>
  8. </template>
  9. <script>
  10. /**
  11. * Badge 数字角标
  12. * @description 数字角标一般和其它控件(列表、9宫格等)配合使用,用于进行数量提示,默认为实心灰色背景
  13. * @tutorial https://ext.dcloud.net.cn/plugin?id=21
  14. * @property {String} text 角标内容
  15. * @property {String} type = [default|primary|success|warning|error] 颜色类型
  16. * @value default 灰色
  17. * @value primary 蓝色
  18. * @value success 绿色
  19. * @value warning 黄色
  20. * @value error 红色
  21. * @property {String} size = [normal|small] Badge 大小
  22. * @value normal 一般尺寸
  23. * @value small 小尺寸
  24. * @property {String} inverted = [true|false] 是否无需背景颜色
  25. * @event {Function} click 点击 Badge 触发事件
  26. * @example <uni-badge text="1"></uni-badge>
  27. */
  28. export default {
  29. name: 'UniBadge',
  30. props: {
  31. type: {
  32. type: String,
  33. default: 'default'
  34. },
  35. inverted: {
  36. type: Boolean,
  37. default: false
  38. },
  39. isDot: {
  40. type: Boolean,
  41. default: false
  42. },
  43. maxNum: {
  44. type: Number,
  45. default: 99
  46. },
  47. absolute: {
  48. type: String,
  49. default: ''
  50. },
  51. offset: {
  52. type: Array,
  53. default () {
  54. return [0, 0]
  55. }
  56. },
  57. text: {
  58. type: [String, Number],
  59. default: ''
  60. },
  61. size: {
  62. type: String,
  63. default: 'normal'
  64. },
  65. customStyle: {
  66. type: Object,
  67. default () {
  68. return {}
  69. }
  70. }
  71. },
  72. data() {
  73. return {};
  74. },
  75. computed: {
  76. width() {
  77. return String(this.text).length * 8 + 12
  78. },
  79. classNames() {
  80. const {
  81. inverted,
  82. type,
  83. size,
  84. absolute
  85. } = this
  86. return [
  87. inverted ? 'uni-badge--' + type + '-inverted' : '',
  88. 'uni-badge--' + type,
  89. 'uni-badge--' + size,
  90. absolute ? 'uni-badge--absolute' : ''
  91. ]
  92. },
  93. positionStyle() {
  94. if (!this.absolute) return {}
  95. let w = this.width / 2,
  96. h = 10
  97. if (this.isDot) {
  98. w = 5
  99. h = 5
  100. }
  101. const x = `${- w + this.offset[0]}px`
  102. const y = `${- h + this.offset[1]}px`
  103. const whiteList = {
  104. rightTop: {
  105. right: x,
  106. top: y
  107. },
  108. rightBottom: {
  109. right: x,
  110. bottom: y
  111. },
  112. leftBottom: {
  113. left: x,
  114. bottom: y
  115. },
  116. leftTop: {
  117. left: x,
  118. top: y
  119. }
  120. }
  121. const match = whiteList[this.absolute]
  122. return match ? match : whiteList['rightTop']
  123. },
  124. badgeWidth() {
  125. return {
  126. width: `${this.width}px`
  127. }
  128. },
  129. dotStyle() {
  130. if (!this.isDot) return {}
  131. return {
  132. width: '10px',
  133. height: '10px',
  134. borderRadius: '10px'
  135. }
  136. },
  137. displayValue() {
  138. const { isDot, text, maxNum } = this
  139. return isDot ? '' : (Number(text) > maxNum ? `${maxNum}+` : text)
  140. }
  141. },
  142. methods: {
  143. onClick() {
  144. this.$emit('click');
  145. }
  146. }
  147. };
  148. </script>
  149. <style lang="scss" scoped>
  150. $bage-size: 12px;
  151. $bage-small: scale(0.8);
  152. $bage-height: 20px;
  153. .uni-badge--x {
  154. /* #ifdef APP-NVUE */
  155. align-self: flex-start;
  156. /* #endif */
  157. /* #ifndef APP-NVUE */
  158. display: inline-block;
  159. /* #endif */
  160. position: relative;
  161. }
  162. .uni-badge--absolute {
  163. position: absolute;
  164. }
  165. .uni-badge {
  166. /* #ifndef APP-NVUE */
  167. display: flex;
  168. overflow: hidden;
  169. box-sizing: border-box;
  170. /* #endif */
  171. justify-content: center;
  172. flex-direction: row;
  173. height: $bage-height;
  174. line-height: $bage-height;
  175. color: $uni-text-color;
  176. border-radius: 100px;
  177. background-color: $uni-bg-color-hover;
  178. background-color: transparent;
  179. text-align: center;
  180. font-family: 'Helvetica Neue', Helvetica, sans-serif;
  181. font-size: $bage-size;
  182. /* #ifdef H5 */
  183. cursor: pointer;
  184. /* #endif */
  185. }
  186. .uni-badge--inverted {
  187. padding: 0 5px 0 0;
  188. color: $uni-bg-color-hover;
  189. }
  190. .uni-badge--default {
  191. color: $uni-text-color;
  192. background-color: $uni-bg-color-hover;
  193. }
  194. .uni-badge--default-inverted {
  195. color: $uni-text-color-grey;
  196. background-color: transparent;
  197. }
  198. .uni-badge--primary {
  199. color: $uni-text-color-inverse;
  200. background-color: $uni-color-primary;
  201. }
  202. .uni-badge--primary-inverted {
  203. color: $uni-color-primary;
  204. background-color: transparent;
  205. }
  206. .uni-badge--success {
  207. color: $uni-text-color-inverse;
  208. background-color: $uni-color-success;
  209. }
  210. .uni-badge--success-inverted {
  211. color: $uni-color-success;
  212. background-color: transparent;
  213. }
  214. .uni-badge--warning {
  215. color: $uni-text-color-inverse;
  216. background-color: $uni-color-warning;
  217. }
  218. .uni-badge--warning-inverted {
  219. color: $uni-color-warning;
  220. background-color: transparent;
  221. }
  222. .uni-badge--error {
  223. color: $uni-text-color-inverse;
  224. background-color: $uni-color-error;
  225. }
  226. .uni-badge--error-inverted {
  227. color: $uni-color-error;
  228. background-color: transparent;
  229. }
  230. .uni-badge--small {
  231. transform: $bage-small;
  232. transform-origin: center center;
  233. }
  234. </style>