金诚优选前端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

259 lines
6.6 KiB

  1. <template>
  2. <view ref="item"
  3. :class="[
  4. 'lb-tabbar-item',
  5. 'animate__animated',
  6. isActive ? 'lb-tabbar-item--active' : ''
  7. ]"
  8. :style="{
  9. paddingTop: paddingBT + raisedeHeight + 'px',
  10. paddingBottom: paddingBT + 'px',
  11. width: '100%'
  12. }"
  13. @tap="handleTap">
  14. <view :class="[
  15. 'lb-tabbar-item__icon',
  16. `lb-tabbar-item__icon--${raisede ? 'raisede' : 'default'}`,
  17. isAnimate ? `animate__animated animate__${tabbarInfo.animate}` : '',
  18. isActive ? 'lb-my-active' : ''
  19. ]"
  20. :style="{
  21. height: tabbarInfo.iconSize,
  22. lineHeight: tabbarInfo.iconSize,
  23. transform: raisede ? `translateY(-${ty}px) scale(${tabbarInfo.raisedeScale})` : ''
  24. }">
  25. <!-- 图片图标 -->
  26. <image v-if="isImage"
  27. class="lb-tabbar-item__image"
  28. :src="icon"
  29. :style="{
  30. width: tabbarInfo.iconSize,
  31. height: tabbarInfo.iconSize
  32. }">
  33. </image>
  34. <!-- icon图标 -->
  35. <text v-else
  36. :class="[
  37. 'lf-iconfont',
  38. iconPrefix,
  39. `${iconPrefix}-${icon}`,
  40. isActive ? 'lb-tabbar-item__icon--active' : ''
  41. ]"
  42. :style="{
  43. width: tabbarInfo.iconSize,
  44. height: tabbarInfo.iconSize,
  45. lineHeight: tabbarInfo.iconSize,
  46. fontSize: tabbarInfo.iconSize,
  47. color: isActive ? tabbarInfo.activeColor : tabbarInfo.inactiveColor
  48. }">{{ iconCode }}</text>
  49. <!-- 非nvue dot info显示 -->
  50. <!-- #ifndef APP-NVUE -->
  51. <text v-if="dot || hasInfo"
  52. :class="[
  53. dot && !hasInfo ? 'lb-tabbar-item__dot' : '',
  54. hasInfo ? 'lb-tabbar-item__dot--info' : '',
  55. 'lb-tabbar-item__dot--style'
  56. ]"
  57. :style="{
  58. backgroundColor: tabbarInfo.dotColor
  59. }">{{ hasInfo ? info : '' }}</text>
  60. <!-- #endif -->
  61. </view>
  62. <!-- nvue dot info 显示 -->
  63. <!-- #ifdef APP-NVUE -->
  64. <text v-if="dot || hasInfo"
  65. :class="[
  66. 'lb-tabbar-item__dot--nvue',
  67. 'lb-tabbar-item__dot--style',
  68. dot && !hasInfo ? 'lb-tabbar-item__dot' : '',
  69. hasInfo ? 'lb-tabbar-item__dot--info' : '',
  70. hasInfo ? 'lb-tabbar-item__dot--info' : '',
  71. nvueDotShow ? 'lb-tabbar-item__dot--show' : ''
  72. ]"
  73. :style="{
  74. backgroundColor: tabbarInfo.dotColor,
  75. top: paddingBT + raisedeHeight + 'px',
  76. right: dotLeft + 'px'
  77. }">{{ hasInfo ? info : '' }}</text>
  78. <!-- #endif -->
  79. <!-- 非nvue图标文字 -->
  80. <!-- #ifndef APP-NVUE -->
  81. <view :class="[
  82. 'lb-tabbar-item__text',
  83. isActive ? 'lb-tabbar-item__text--active' : ''
  84. ]"
  85. :style="{
  86. fontSize: tabbarInfo.textSize,
  87. lineHeight: tabbarInfo.textSize,
  88. maxHeight: tabbarInfo.textSize,
  89. marginTop: tabbarInfo.textTop,
  90. color: isActive
  91. ? tabbarInfo.activeTextColor || tabbarInfo.activeColor
  92. : tabbarInfo.inactiveTextColor || tabbarInfo.inactiveColor
  93. }">
  94. <slot></slot>
  95. <view v-if="raisede"
  96. class="lb-tabbar-item__text--block"
  97. :style="{
  98. height: tabbarInfo.textSize
  99. }">
  100. </view>
  101. </view>
  102. <!-- #endif -->
  103. <!-- nvue图标文字 -->
  104. <!-- #ifdef APP-NVUE -->
  105. <text v-if="text || raisede"
  106. :class="[
  107. 'lb-tabbar-item__text',
  108. isActive ? 'lb-tabbar-item__text--active' : ''
  109. ]"
  110. :style="{
  111. fontSize: tabbarInfo.textSize,
  112. height: tabbarInfo.textSize,
  113. lineHeight: tabbarInfo.textSize,
  114. marginTop: tabbarInfo.textTop,
  115. color: isActive
  116. ? tabbarInfo.activeTextColor || tabbarInfo.activeColor
  117. : tabbarInfo.inactiveTextColor || tabbarInfo.inactiveColor
  118. }">{{ text || '' }}</text>
  119. <!-- #endif -->
  120. </view>
  121. </template>
  122. <script>
  123. // #ifdef APP-NVUE
  124. const dom = uni.requireNativePlugin('dom')
  125. // #endif
  126. import { getPx } from './utils'
  127. export default {
  128. props: {
  129. name: [String, Number],
  130. text: [String, Number],
  131. icon: String,
  132. iconPrefix: String,
  133. dot: Boolean,
  134. info: [String, Number],
  135. raisede: Boolean,
  136. path: String
  137. },
  138. inject: ['tabbar'],
  139. data () {
  140. return {
  141. tabbarInfo: {},
  142. itemWidth: 0,
  143. dotLeft: 0,
  144. nvueDotShow: false
  145. }
  146. },
  147. computed: {
  148. isImage () {
  149. return this.icon && this.icon.indexOf('/') > -1
  150. },
  151. isActive () {
  152. return this.tabbarInfo.value === this.name
  153. },
  154. isAnimate () {
  155. return (
  156. this.isActive &&
  157. this.tabbarInfo.animate &&
  158. !(this.raisede && this.tabbarInfo.closeAnimateOnRaisede)
  159. )
  160. },
  161. height () {
  162. return getPx(this.tabbarInfo.height)
  163. },
  164. iconHeight () {
  165. return getPx(this.tabbarInfo.iconSize)
  166. },
  167. textSize () {
  168. return getPx(this.tabbarInfo.textSize)
  169. },
  170. textTop () {
  171. return getPx(this.tabbarInfo.textTop)
  172. },
  173. ty () {
  174. return this.height / 2 - (this.textSize + this.textTop) / 2
  175. },
  176. iconCode () {
  177. let code = ''
  178. // #ifdef APP-NVUE
  179. code = this.icon
  180. // #endif
  181. return code
  182. },
  183. hasInfo () {
  184. return this.info || this.info === 0
  185. },
  186. paddingBT () {
  187. return (this.height - this.iconHeight - this.textSize - this.textTop) / 2
  188. },
  189. hasRaisede () {
  190. return this.tabbar.hasRaisede
  191. },
  192. raisedeHeight () {
  193. return this.hasRaisede ? this.iconHeight * this.tabbarInfo.raisedeScale / 2 : 0 // 凸起高度
  194. },
  195. infoLength () {
  196. return this.hasInfo ? (this.info + '').length : 0
  197. }
  198. },
  199. created () {
  200. this.tabbarInfo = this.tabbar._props
  201. this.tabbar.tabbarItems.push(this._props)
  202. },
  203. mounted() {
  204. // #ifdef APP-NVUE
  205. this.setNvueDot()
  206. // #endif
  207. },
  208. methods: {
  209. handleTap () {
  210. this.tabbar.active = this.name
  211. this.$emit('click', this._props)
  212. },
  213. // #ifdef APP-NVUE
  214. setNvueDot () {
  215. if (this.dot || this.hasInfo) {
  216. this.$nextTick(() => {
  217. const $el = this.$refs.item
  218. dom.getComponentRect($el, res => {
  219. this.itemWidth = res.size.width
  220. const halfWidth = this.itemWidth / 2
  221. if (this.dot) {
  222. this.dotLeft = halfWidth - 8
  223. }
  224. if (this.hasInfo) {
  225. const length = this.infoLength > 1 ? this.infoLength -1 : this.infoLength
  226. this.dotLeft = halfWidth - 8 * length
  227. }
  228. this.nvueDotShow = true
  229. })
  230. })
  231. }
  232. }
  233. // #endif
  234. },
  235. // #ifdef APP-NVUE
  236. watch: {
  237. dot () {
  238. this.setNvueDot()
  239. },
  240. info () {
  241. this.setNvueDot()
  242. }
  243. }
  244. // #endif
  245. }
  246. </script>
  247. <style lang="scss" scoped>
  248. @import "./style.scss";
  249. /* #ifndef APP-NVUE */
  250. @import "./animate.scss";
  251. /* #endif */
  252. </style>