u-tabs.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  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$13],
  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. if (typeof newValue == "string") {
  25. this.innerCurrent = parseInt(newValue);
  26. } else {
  27. this.innerCurrent = newValue;
  28. }
  29. this.$nextTick(() => {
  30. this.resize();
  31. });
  32. }
  33. }
  34. },
  35. // list变化时,重新渲染list各项信息
  36. list() {
  37. this.$nextTick(() => {
  38. this.resize();
  39. });
  40. }
  41. },
  42. computed: {
  43. textStyle() {
  44. return (index) => {
  45. const style = {};
  46. const customeStyle = index == this.innerCurrent ? common_vendor.addStyle(this.activeStyle) : common_vendor.addStyle(this.inactiveStyle);
  47. if (this.list[index].disabled) {
  48. style.color = "#c8c9cc";
  49. }
  50. return common_vendor.deepMerge(customeStyle, style);
  51. };
  52. },
  53. propsBadge() {
  54. return common_vendor.props$14.badge;
  55. }
  56. },
  57. async mounted() {
  58. this.init();
  59. },
  60. emits: ["click", "longPress", "change", "update:current"],
  61. methods: {
  62. addStyle: common_vendor.addStyle,
  63. addUnit: common_vendor.addUnit,
  64. setLineLeft() {
  65. const tabItem = this.list[this.innerCurrent];
  66. if (!tabItem) {
  67. return;
  68. }
  69. let lineOffsetLeft = this.list.slice(0, this.innerCurrent).reduce((total, curr) => total + curr.rect.width, 0);
  70. const lineWidth = common_vendor.getPx(this.lineWidth);
  71. this.lineOffsetLeft = lineOffsetLeft + (tabItem.rect.width - lineWidth) / 2;
  72. if (this.firstTime) {
  73. setTimeout(() => {
  74. this.firstTime = false;
  75. }, 10);
  76. }
  77. },
  78. // nvue下设置滑块的位置
  79. animation(x, duration = 0) {
  80. },
  81. // 点击某一个标签
  82. clickHandler(item, index) {
  83. this.$emit("click", {
  84. ...item,
  85. index
  86. }, index);
  87. if (item.disabled)
  88. return;
  89. this.innerCurrent = index;
  90. this.resize();
  91. this.$emit("update:current", index);
  92. this.$emit("change", {
  93. ...item,
  94. index
  95. }, index);
  96. },
  97. // 长按事件
  98. longPressHandler(item, index) {
  99. this.$emit("longPress", {
  100. ...item,
  101. index
  102. });
  103. },
  104. init() {
  105. common_vendor.sleep().then(() => {
  106. this.resize();
  107. });
  108. },
  109. setScrollLeft() {
  110. if (this.innerCurrent < 0) {
  111. this.innerCurrent = 0;
  112. }
  113. const tabRect = this.list[this.innerCurrent];
  114. const offsetLeft = this.list.slice(0, this.innerCurrent).reduce((total, curr) => {
  115. return total + curr.rect.width;
  116. }, 0);
  117. const windowWidth = common_vendor.getWindowInfo().windowWidth;
  118. let scrollLeft = offsetLeft - (this.tabsRect.width - tabRect.rect.width) / 2 - (windowWidth - this.tabsRect.right) / 2 + this.tabsRect.left / 2;
  119. scrollLeft = Math.min(scrollLeft, this.scrollViewWidth - this.tabsRect.width);
  120. this.scrollLeft = Math.max(0, scrollLeft);
  121. },
  122. // 获取所有标签的尺寸
  123. resize() {
  124. if (this.list.length === 0) {
  125. return;
  126. }
  127. Promise.all([this.getTabsRect(), this.getAllItemRect()]).then(([tabsRect, itemRect = []]) => {
  128. if (tabsRect.left > tabsRect.width) {
  129. tabsRect.right = tabsRect.right - Math.floor(tabsRect.left / tabsRect.width) * tabsRect.width;
  130. tabsRect.left = tabsRect.left % tabsRect.width;
  131. }
  132. this.tabsRect = tabsRect;
  133. this.scrollViewWidth = 0;
  134. itemRect.map((item, index) => {
  135. this.scrollViewWidth += item.width;
  136. this.list[index].rect = item;
  137. });
  138. this.setLineLeft();
  139. this.setScrollLeft();
  140. });
  141. },
  142. // 获取导航菜单的尺寸
  143. getTabsRect() {
  144. return new Promise((resolve) => {
  145. this.queryRect("u-tabs__wrapper__scroll-view").then((size) => resolve(size));
  146. });
  147. },
  148. // 获取所有标签的尺寸
  149. getAllItemRect() {
  150. return new Promise((resolve) => {
  151. const promiseAllArr = this.list.map((item, index) => this.queryRect(
  152. `u-tabs__wrapper__nav__item-${index}`,
  153. true
  154. ));
  155. Promise.all(promiseAllArr).then((sizes) => resolve(sizes));
  156. });
  157. },
  158. // 获取各个标签的尺寸
  159. queryRect(el, item) {
  160. return new Promise((resolve) => {
  161. this.$uGetRect(`.${el}`).then((size) => {
  162. resolve(size);
  163. });
  164. });
  165. }
  166. }
  167. };
  168. if (!Array) {
  169. const _easycom_up_icon2 = common_vendor.resolveComponent("up-icon");
  170. const _easycom_u_badge2 = common_vendor.resolveComponent("u-badge");
  171. (_easycom_up_icon2 + _easycom_u_badge2)();
  172. }
  173. const _easycom_up_icon = () => "../u-icon/u-icon.js";
  174. const _easycom_u_badge = () => "../u-badge/u-badge.js";
  175. if (!Math) {
  176. (_easycom_up_icon + _easycom_u_badge)();
  177. }
  178. function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
  179. return {
  180. a: common_vendor.f(_ctx.list, (item, index, i0) => {
  181. return common_vendor.e(_ctx.$slots.icon ? {
  182. a: "icon-" + i0,
  183. b: common_vendor.r("icon", {
  184. item,
  185. keyName: _ctx.keyName,
  186. index
  187. }, i0)
  188. } : common_vendor.e({
  189. c: item.icon
  190. }, item.icon ? {
  191. d: "0546c3e4-0-" + i0,
  192. e: common_vendor.p({
  193. name: item.icon,
  194. customStyle: $options.addStyle(_ctx.iconStyle)
  195. })
  196. } : {}), _ctx.$slots.content ? {
  197. f: "content-" + i0,
  198. g: common_vendor.r("content", {
  199. item,
  200. keyName: _ctx.keyName,
  201. index
  202. }, i0)
  203. } : !_ctx.$slots.content && (_ctx.$slots.default || _ctx.$slots.$default) ? {
  204. h: "d-" + i0,
  205. i: common_vendor.r("d", {
  206. item,
  207. keyName: _ctx.keyName,
  208. index
  209. }, i0)
  210. } : {
  211. j: common_vendor.t(item[_ctx.keyName]),
  212. k: common_vendor.n(item.disabled && "u-tabs__wrapper__nav__item__text--disabled"),
  213. l: common_vendor.s($options.textStyle(index))
  214. }, {
  215. m: "0546c3e4-1-" + i0,
  216. n: common_vendor.p({
  217. show: !!(item.badge && (item.badge.show || item.badge.isDot || item.badge.value)),
  218. isDot: item.badge && item.badge.isDot || $options.propsBadge.isDot,
  219. value: item.badge && item.badge.value || $options.propsBadge.value,
  220. max: item.badge && item.badge.max || $options.propsBadge.max,
  221. type: item.badge && item.badge.type || $options.propsBadge.type,
  222. showZero: item.badge && item.badge.showZero || $options.propsBadge.showZero,
  223. bgColor: item.badge && item.badge.bgColor || $options.propsBadge.bgColor,
  224. color: item.badge && item.badge.color || $options.propsBadge.color,
  225. shape: item.badge && item.badge.shape || $options.propsBadge.shape,
  226. numberType: item.badge && item.badge.numberType || $options.propsBadge.numberType,
  227. inverted: item.badge && item.badge.inverted || $options.propsBadge.inverted,
  228. customStyle: "margin-left: 4px;"
  229. }),
  230. o: index,
  231. p: common_vendor.o(($event) => $options.clickHandler(item, index), index),
  232. q: common_vendor.o(($event) => $options.longPressHandler(item, index), index),
  233. r: `u-tabs__wrapper__nav__item-${index}`,
  234. s: common_vendor.n(`u-tabs__wrapper__nav__item-${index}`),
  235. t: common_vendor.n(item.disabled && "u-tabs__wrapper__nav__item--disabled"),
  236. v: common_vendor.n($data.innerCurrent == index ? "u-tabs__wrapper__nav__item-active" : "")
  237. });
  238. }),
  239. b: _ctx.$slots.icon,
  240. c: _ctx.$slots.content,
  241. d: !_ctx.$slots.content && (_ctx.$slots.default || _ctx.$slots.$default),
  242. e: common_vendor.s($options.addStyle(_ctx.itemStyle)),
  243. f: common_vendor.s({
  244. flex: _ctx.scrollable ? "" : 1
  245. }),
  246. g: common_vendor.s({
  247. width: $options.addUnit(_ctx.lineWidth),
  248. transform: `translate(${$data.lineOffsetLeft}px)`,
  249. transitionDuration: `${$data.firstTime ? 0 : _ctx.duration}ms`,
  250. height: $options.addUnit(_ctx.lineHeight),
  251. background: _ctx.lineColor,
  252. backgroundSize: _ctx.lineBgSize
  253. }),
  254. h: _ctx.scrollable,
  255. i: $data.scrollLeft,
  256. j: common_vendor.n(_ctx.customClass)
  257. };
  258. }
  259. const Component = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-0546c3e4"], ["__file", "C:/Users/Administrator/Desktop/srcaaa/node_modules/uview-plus/components/u-tabs/u-tabs.vue"]]);
  260. wx.createComponent(Component);