u-tabs.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. "use strict";
  2. const common_vendor = require("../../../../common/vendor.js");
  3. const _sfc_main = {
  4. name: "u-tabs",
  5. mixins: [common_vendor.mpMixin, common_vendor.mixin, common_vendor.props$2],
  6. data() {
  7. return {
  8. firstTime: true,
  9. scrollLeft: 0,
  10. scrollViewWidth: 0,
  11. lineOffsetLeft: 0,
  12. tabsRect: {
  13. left: 0
  14. },
  15. innerCurrent: 0,
  16. moving: false
  17. };
  18. },
  19. watch: {
  20. current: {
  21. immediate: true,
  22. handler(newValue, oldValue) {
  23. if (newValue !== this.innerCurrent) {
  24. this.innerCurrent = newValue;
  25. this.$nextTick(() => {
  26. this.resize();
  27. });
  28. }
  29. }
  30. },
  31. // list变化时,重新渲染list各项信息
  32. list() {
  33. this.$nextTick(() => {
  34. this.resize();
  35. });
  36. }
  37. },
  38. computed: {
  39. textStyle() {
  40. return (index) => {
  41. const style = {};
  42. const customeStyle = index === this.innerCurrent ? common_vendor.addStyle(this.activeStyle) : common_vendor.addStyle(this.inactiveStyle);
  43. if (this.list[index].disabled) {
  44. style.color = "#c8c9cc";
  45. }
  46. return common_vendor.deepMerge(customeStyle, style);
  47. };
  48. },
  49. propsBadge() {
  50. return common_vendor.defProps.badge;
  51. }
  52. },
  53. async mounted() {
  54. this.init();
  55. },
  56. emits: ["click", "change"],
  57. methods: {
  58. addStyle: common_vendor.addStyle,
  59. addUnit: common_vendor.addUnit,
  60. setLineLeft() {
  61. const tabItem = this.list[this.innerCurrent];
  62. if (!tabItem) {
  63. return;
  64. }
  65. let lineOffsetLeft = this.list.slice(0, this.innerCurrent).reduce((total, curr) => total + curr.rect.width, 0);
  66. const lineWidth = common_vendor.getPx(this.lineWidth);
  67. this.lineOffsetLeft = lineOffsetLeft + (tabItem.rect.width - lineWidth) / 2;
  68. if (this.firstTime) {
  69. setTimeout(() => {
  70. this.firstTime = false;
  71. }, 10);
  72. }
  73. },
  74. // nvue下设置滑块的位置
  75. animation(x, duration = 0) {
  76. },
  77. // 点击某一个标签
  78. clickHandler(item, index) {
  79. this.$emit("click", {
  80. ...item,
  81. index
  82. }, index);
  83. if (item.disabled)
  84. return;
  85. this.innerCurrent = index;
  86. this.resize();
  87. this.$emit("change", {
  88. ...item,
  89. index
  90. }, index);
  91. },
  92. init() {
  93. common_vendor.sleep().then(() => {
  94. this.resize();
  95. });
  96. },
  97. setScrollLeft() {
  98. const tabRect = this.list[this.innerCurrent];
  99. const offsetLeft = this.list.slice(0, this.innerCurrent).reduce((total, curr) => {
  100. return total + curr.rect.width;
  101. }, 0);
  102. const windowWidth = common_vendor.sys().windowWidth;
  103. let scrollLeft = offsetLeft - (this.tabsRect.width - tabRect.rect.width) / 2 - (windowWidth - this.tabsRect.right) / 2 + this.tabsRect.left / 2;
  104. scrollLeft = Math.min(scrollLeft, this.scrollViewWidth - this.tabsRect.width);
  105. this.scrollLeft = Math.max(0, scrollLeft);
  106. },
  107. // 获取所有标签的尺寸
  108. resize() {
  109. if (this.list.length === 0) {
  110. return;
  111. }
  112. Promise.all([this.getTabsRect(), this.getAllItemRect()]).then(([tabsRect, itemRect = []]) => {
  113. this.tabsRect = tabsRect;
  114. this.scrollViewWidth = 0;
  115. itemRect.map((item, index) => {
  116. this.scrollViewWidth += item.width;
  117. this.list[index].rect = item;
  118. });
  119. this.setLineLeft();
  120. this.setScrollLeft();
  121. });
  122. },
  123. // 获取导航菜单的尺寸
  124. getTabsRect() {
  125. return new Promise((resolve) => {
  126. this.queryRect("u-tabs__wrapper__scroll-view").then((size) => resolve(size));
  127. });
  128. },
  129. // 获取所有标签的尺寸
  130. getAllItemRect() {
  131. return new Promise((resolve) => {
  132. const promiseAllArr = this.list.map((item, index) => this.queryRect(
  133. `u-tabs__wrapper__nav__item-${index}`,
  134. true
  135. ));
  136. Promise.all(promiseAllArr).then((sizes) => resolve(sizes));
  137. });
  138. },
  139. // 获取各个标签的尺寸
  140. queryRect(el, item) {
  141. return new Promise((resolve) => {
  142. this.$uGetRect(`.${el}`).then((size) => {
  143. resolve(size);
  144. });
  145. });
  146. }
  147. }
  148. };
  149. if (!Array) {
  150. const _easycom_u_badge2 = common_vendor.resolveComponent("u-badge");
  151. _easycom_u_badge2();
  152. }
  153. const _easycom_u_badge = () => "../u-badge/u-badge.js";
  154. if (!Math) {
  155. _easycom_u_badge();
  156. }
  157. function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
  158. return {
  159. a: common_vendor.f(_ctx.list, (item, index, i0) => {
  160. return {
  161. a: common_vendor.t(item[_ctx.keyName]),
  162. b: common_vendor.n(item.disabled && "u-tabs__wrapper__nav__item__text--disabled"),
  163. c: common_vendor.s($options.textStyle(index)),
  164. d: "0546c3e4-0-" + i0,
  165. e: common_vendor.p({
  166. show: !!(item.badge && (item.badge.show || item.badge.isDot || item.badge.value)),
  167. isDot: item.badge && item.badge.isDot || $options.propsBadge.isDot,
  168. value: item.badge && item.badge.value || $options.propsBadge.value,
  169. max: item.badge && item.badge.max || $options.propsBadge.max,
  170. type: item.badge && item.badge.type || $options.propsBadge.type,
  171. showZero: item.badge && item.badge.showZero || $options.propsBadge.showZero,
  172. bgColor: item.badge && item.badge.bgColor || $options.propsBadge.bgColor,
  173. color: item.badge && item.badge.color || $options.propsBadge.color,
  174. shape: item.badge && item.badge.shape || $options.propsBadge.shape,
  175. numberType: item.badge && item.badge.numberType || $options.propsBadge.numberType,
  176. inverted: item.badge && item.badge.inverted || $options.propsBadge.inverted,
  177. customStyle: "margin-left: 4px;"
  178. }),
  179. f: index,
  180. g: common_vendor.o(($event) => $options.clickHandler(item, index), index),
  181. h: `u-tabs__wrapper__nav__item-${index}`,
  182. i: common_vendor.n(`u-tabs__wrapper__nav__item-${index}`),
  183. j: common_vendor.n(item.disabled && "u-tabs__wrapper__nav__item--disabled")
  184. };
  185. }),
  186. b: common_vendor.s($options.addStyle(_ctx.itemStyle)),
  187. c: common_vendor.s({
  188. flex: _ctx.scrollable ? "" : 1
  189. }),
  190. d: common_vendor.s({
  191. width: $options.addUnit(_ctx.lineWidth),
  192. transform: `translate(${$data.lineOffsetLeft}px)`,
  193. transitionDuration: `${$data.firstTime ? 0 : _ctx.duration}ms`,
  194. height: $options.addUnit(_ctx.lineHeight),
  195. background: _ctx.lineColor,
  196. backgroundSize: _ctx.lineBgSize
  197. }),
  198. e: _ctx.scrollable,
  199. f: $data.scrollLeft
  200. };
  201. }
  202. const Component = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-0546c3e4"], ["__file", "D:/project/学吧/learn_applet/node_modules/uview-plus/components/u-tabs/u-tabs.vue"]]);
  203. wx.createComponent(Component);