cl-tabbar-item.vue 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. <template>
  2. <view
  3. class="cl-tabbar-item"
  4. :class="[classList]"
  5. :style="[
  6. {
  7. height: parent.height,
  8. width,
  9. },
  10. ]"
  11. @tap="tapItem"
  12. >
  13. <!-- 处理小程序slot异常 -->
  14. <slot v-if="$slots.$default || $slots.default"></slot>
  15. <!-- 默认内容 -->
  16. <cl-badge :value="badge" v-else>
  17. <view class="cl-tabbar-item__block">
  18. <image
  19. class="cl-tabbar-item__image icon-path"
  20. :src="iconPath"
  21. :style="{
  22. height: size,
  23. width: size,
  24. }"
  25. />
  26. <image
  27. class="cl-tabbar-item__image selected-icon-path"
  28. :src="selectedIconPath"
  29. :style="{
  30. height: size,
  31. width: size,
  32. }"
  33. />
  34. <text
  35. v-if="text"
  36. class="cl-tabbar-item__label"
  37. :style="{
  38. color,
  39. }"
  40. >{{ text }}</text
  41. >
  42. </view>
  43. </cl-badge>
  44. </view>
  45. </template>
  46. <script>
  47. import Emitter from "../../mixins/emitter";
  48. import Parent from "../../mixins/parent";
  49. import { parseRpx } from "../../utils";
  50. /**
  51. * tabbar-item 底部导航项
  52. * @description 该组件与原生tabbar配置一致,同时添加新的支持。
  53. * @tutorial https://docs.cool-js.com/uni/components/nav/tabbar.html
  54. * @property {String} text 文本内容
  55. * @property {String, Number} name 唯一标识
  56. * @property {String} iconPath 图标路径
  57. * @property {String} selectedIconPath 选中的图标路径
  58. * @property {Number} iconSize 图标大小,默认50
  59. * @property {Number, String} badge 角标值
  60. * @example 见教程
  61. */
  62. export default {
  63. name: "cl-tabbar-item",
  64. componentName: "ClTabbarItem",
  65. props: {
  66. // 文本内容
  67. text: String,
  68. // 唯一标识
  69. name: {
  70. type: [String, Number],
  71. required: true,
  72. },
  73. // 图标路径
  74. iconPath: String,
  75. // 选中的图标路径
  76. selectedIconPath: String,
  77. // 图标大小
  78. iconSize: {
  79. type: Number,
  80. default: 50,
  81. },
  82. // 角标值
  83. badge: {
  84. type: [Number, String],
  85. default: 0,
  86. },
  87. },
  88. mixins: [Emitter, Parent],
  89. data() {
  90. return {
  91. Keys: ["name", "color", "selectedColor", "height", "width", "number"],
  92. ComponentName: "ClTabbar",
  93. };
  94. },
  95. computed: {
  96. size() {
  97. return parseRpx(this.iconSize);
  98. },
  99. color() {
  100. return this.isActive ? this.parent.selectedColor : this.parent.color;
  101. },
  102. src() {
  103. return this.isActive ? this.selectedIconPath : this.iconPath;
  104. },
  105. width() {
  106. // #ifdef MP-TOUTIAO
  107. return parseInt(100 / this.parent.number) + "%";
  108. // #endif
  109. // #ifndef MP-TOUTIAO
  110. return "100%";
  111. // #endif
  112. },
  113. isActive() {
  114. return this.name !== null && this.parent && this.parent.name === this.name;
  115. },
  116. classList() {
  117. let list = [];
  118. if (this.isActive) {
  119. list.push("is-active");
  120. }
  121. return list.join(" ");
  122. },
  123. },
  124. methods: {
  125. tapItem() {
  126. this.dispatch("ClTabbar", "change", this.name);
  127. },
  128. },
  129. };
  130. </script>