uni-badge.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  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. emits:['click'],
  31. props: {
  32. type: {
  33. type: String,
  34. default: 'default'
  35. },
  36. inverted: {
  37. type: Boolean,
  38. default: false
  39. },
  40. isDot: {
  41. type: Boolean,
  42. default: false
  43. },
  44. maxNum: {
  45. type: Number,
  46. default: 99
  47. },
  48. absolute: {
  49. type: String,
  50. default: ''
  51. },
  52. offset: {
  53. type: Array,
  54. default () {
  55. return [0, 0]
  56. }
  57. },
  58. text: {
  59. type: [String, Number],
  60. default: ''
  61. },
  62. size: {
  63. type: String,
  64. default: 'normal'
  65. },
  66. customStyle: {
  67. type: Object,
  68. default () {
  69. return {}
  70. }
  71. }
  72. },
  73. data() {
  74. return {};
  75. },
  76. computed: {
  77. width() {
  78. return String(this.text).length * 8 + 12
  79. },
  80. classNames() {
  81. const {
  82. inverted,
  83. type,
  84. size,
  85. absolute
  86. } = this
  87. return [
  88. inverted ? 'uni-badge--' + type + '-inverted' : '',
  89. 'uni-badge--' + type,
  90. 'uni-badge--' + size,
  91. absolute ? 'uni-badge--absolute' : ''
  92. ].join(' ')
  93. },
  94. positionStyle() {
  95. if (!this.absolute) return {}
  96. let w = this.width / 2,
  97. h = 10
  98. if (this.isDot) {
  99. w = 5
  100. h = 5
  101. }
  102. const x = `${- w + this.offset[0]}px`
  103. const y = `${- h + this.offset[1]}px`
  104. const whiteList = {
  105. rightTop: {
  106. right: x,
  107. top: y
  108. },
  109. rightBottom: {
  110. right: x,
  111. bottom: y
  112. },
  113. leftBottom: {
  114. left: x,
  115. bottom: y
  116. },
  117. leftTop: {
  118. left: x,
  119. top: y
  120. }
  121. }
  122. const match = whiteList[this.absolute]
  123. return match ? match : whiteList['rightTop']
  124. },
  125. badgeWidth() {
  126. return {
  127. width: `${this.width}px`
  128. }
  129. },
  130. dotStyle() {
  131. if (!this.isDot) return {}
  132. return {
  133. width: '10px',
  134. height: '10px',
  135. borderRadius: '10px'
  136. }
  137. },
  138. displayValue() {
  139. const { isDot, text, maxNum } = this
  140. return isDot ? '' : (Number(text) > maxNum ? `${maxNum}+` : text)
  141. }
  142. },
  143. methods: {
  144. onClick() {
  145. this.$emit('click');
  146. }
  147. }
  148. };
  149. </script>
  150. <style lang="scss" scoped>
  151. $bage-size: 12px;
  152. $bage-small: scale(0.8);
  153. $bage-height: 20px;
  154. .uni-badge--x {
  155. /* #ifdef APP-NVUE */
  156. // align-self: flex-start;
  157. /* #endif */
  158. /* #ifndef APP-NVUE */
  159. display: inline-block;
  160. /* #endif */
  161. position: relative;
  162. }
  163. .uni-badge--absolute {
  164. position: absolute;
  165. }
  166. .uni-badge {
  167. /* #ifndef APP-NVUE */
  168. display: flex;
  169. overflow: hidden;
  170. box-sizing: border-box;
  171. /* #endif */
  172. justify-content: center;
  173. flex-direction: row;
  174. height: $bage-height;
  175. line-height: $bage-height;
  176. color: $uni-text-color;
  177. border-radius: 100px;
  178. background-color: $uni-bg-color-hover;
  179. background-color: transparent;
  180. text-align: center;
  181. font-family: 'Helvetica Neue', Helvetica, sans-serif;
  182. font-size: $bage-size;
  183. /* #ifdef H5 */
  184. cursor: pointer;
  185. /* #endif */
  186. }
  187. .uni-badge--inverted {
  188. padding: 0 5px 0 0;
  189. color: $uni-bg-color-hover;
  190. }
  191. .uni-badge--default {
  192. color: $uni-text-color;
  193. background-color: $uni-bg-color-hover;
  194. }
  195. .uni-badge--default-inverted {
  196. color: $uni-text-color-grey;
  197. background-color: transparent;
  198. }
  199. .uni-badge--primary {
  200. color: $uni-text-color-inverse;
  201. background-color: $uni-color-primary;
  202. }
  203. .uni-badge--primary-inverted {
  204. color: $uni-color-primary;
  205. background-color: transparent;
  206. }
  207. .uni-badge--success {
  208. color: $uni-text-color-inverse;
  209. background-color: $uni-color-success;
  210. }
  211. .uni-badge--success-inverted {
  212. color: $uni-color-success;
  213. background-color: transparent;
  214. }
  215. .uni-badge--warning {
  216. color: $uni-text-color-inverse;
  217. background-color: $uni-color-warning;
  218. }
  219. .uni-badge--warning-inverted {
  220. color: $uni-color-warning;
  221. background-color: transparent;
  222. }
  223. .uni-badge--error {
  224. color: $uni-text-color-inverse;
  225. background-color: $uni-color-error;
  226. }
  227. .uni-badge--error-inverted {
  228. color: $uni-color-error;
  229. background-color: transparent;
  230. }
  231. .uni-badge--small {
  232. transform: $bage-small;
  233. transform-origin: center center;
  234. }
  235. </style>