index.js 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. var component_1 = require("../common/component");
  4. var touch_1 = require("../mixins/touch");
  5. var utils_1 = require("../common/utils");
  6. component_1.VantComponent({
  7. mixins: [touch_1.touch],
  8. classes: ['nav-class', 'tab-class', 'tab-active-class', 'line-class'],
  9. relation: {
  10. name: 'tab',
  11. type: 'descendant',
  12. current: 'tabs',
  13. linked: function (target) {
  14. target.index = this.children.length - 1;
  15. this.updateTabs();
  16. },
  17. unlinked: function () {
  18. this.children = this.children
  19. .map(function (child, index) {
  20. child.index = index;
  21. return child;
  22. });
  23. this.updateTabs();
  24. }
  25. },
  26. props: {
  27. color: {
  28. type: String,
  29. observer: 'setLine'
  30. },
  31. sticky: Boolean,
  32. animated: {
  33. type: Boolean,
  34. observer: function () {
  35. var _this = this;
  36. this.children.forEach(function (child, index) {
  37. return child.updateRender(index === _this.data.currentIndex, _this);
  38. });
  39. }
  40. },
  41. swipeable: Boolean,
  42. lineWidth: {
  43. type: [String, Number],
  44. value: -1,
  45. observer: 'setLine'
  46. },
  47. lineHeight: {
  48. type: [String, Number],
  49. value: -1,
  50. observer: 'setLine'
  51. },
  52. titleActiveColor: String,
  53. titleInactiveColor: String,
  54. active: {
  55. type: [String, Number],
  56. value: 0,
  57. observer: function (name) {
  58. if (name !== this.getCurrentName()) {
  59. this.setCurrentIndexByName(name);
  60. }
  61. }
  62. },
  63. type: {
  64. type: String,
  65. value: 'line'
  66. },
  67. border: {
  68. type: Boolean,
  69. value: true
  70. },
  71. ellipsis: {
  72. type: Boolean,
  73. value: true
  74. },
  75. duration: {
  76. type: Number,
  77. value: 0.3
  78. },
  79. zIndex: {
  80. type: Number,
  81. value: 1
  82. },
  83. swipeThreshold: {
  84. type: Number,
  85. value: 4,
  86. observer: function (value) {
  87. this.setData({
  88. scrollable: this.children.length > value || !this.data.ellipsis
  89. });
  90. }
  91. },
  92. offsetTop: {
  93. type: Number,
  94. value: 0
  95. },
  96. lazyRender: {
  97. type: Boolean,
  98. value: true
  99. }
  100. },
  101. data: {
  102. tabs: [],
  103. lineStyle: '',
  104. scrollLeft: 0,
  105. scrollable: false,
  106. trackStyle: '',
  107. currentIndex: null,
  108. container: null
  109. },
  110. mounted: function () {
  111. var _this = this;
  112. wx.nextTick(function () {
  113. _this.setLine(true);
  114. _this.scrollIntoView();
  115. });
  116. },
  117. methods: {
  118. updateContainer: function () {
  119. var _this = this;
  120. this.setData({
  121. container: function () { return _this.createSelectorQuery().select('.van-tabs'); }
  122. });
  123. },
  124. updateTabs: function () {
  125. var _a = this, _b = _a.children, children = _b === void 0 ? [] : _b, data = _a.data;
  126. this.setData({
  127. tabs: children.map(function (child) { return child.data; }),
  128. scrollable: this.children.length > data.swipeThreshold || !data.ellipsis
  129. });
  130. this.setCurrentIndexByName(this.getCurrentName() || data.active);
  131. },
  132. trigger: function (eventName, child) {
  133. var currentIndex = this.data.currentIndex;
  134. var currentChild = child || this.children[currentIndex];
  135. if (!utils_1.isDef(currentChild)) {
  136. return;
  137. }
  138. this.$emit(eventName, {
  139. index: currentChild.index,
  140. name: currentChild.getComputedName(),
  141. title: currentChild.data.title
  142. });
  143. },
  144. onTap: function (event) {
  145. var _this = this;
  146. var index = event.currentTarget.dataset.index;
  147. var child = this.children[index];
  148. if (child.data.disabled) {
  149. this.trigger('disabled', child);
  150. }
  151. else {
  152. this.setCurrentIndex(index);
  153. wx.nextTick(function () {
  154. _this.trigger('click');
  155. });
  156. }
  157. },
  158. // correct the index of active tab
  159. setCurrentIndexByName: function (name) {
  160. var _a = this.children, children = _a === void 0 ? [] : _a;
  161. var matched = children.filter(function (child) { return child.getComputedName() === name; });
  162. if (matched.length) {
  163. this.setCurrentIndex(matched[0].index);
  164. }
  165. },
  166. setCurrentIndex: function (currentIndex) {
  167. var _this = this;
  168. var _a = this, data = _a.data, _b = _a.children, children = _b === void 0 ? [] : _b;
  169. if (!utils_1.isDef(currentIndex) ||
  170. currentIndex >= children.length ||
  171. currentIndex < 0) {
  172. return;
  173. }
  174. children.forEach(function (item, index) {
  175. var active = index === currentIndex;
  176. if (active !== item.data.active || !item.inited) {
  177. item.updateRender(active, _this);
  178. }
  179. });
  180. if (currentIndex === data.currentIndex) {
  181. return;
  182. }
  183. var shouldEmitChange = data.currentIndex !== null;
  184. this.setData({ currentIndex: currentIndex });
  185. wx.nextTick(function () {
  186. _this.setLine();
  187. _this.scrollIntoView();
  188. _this.updateContainer();
  189. _this.trigger('input');
  190. if (shouldEmitChange) {
  191. _this.trigger('change');
  192. }
  193. });
  194. },
  195. getCurrentName: function () {
  196. var activeTab = this.children[this.data.currentIndex];
  197. if (activeTab) {
  198. return activeTab.getComputedName();
  199. }
  200. },
  201. setLine: function (skipTransition) {
  202. var _this = this;
  203. if (this.data.type !== 'line') {
  204. return;
  205. }
  206. var _a = this.data, color = _a.color, duration = _a.duration, currentIndex = _a.currentIndex, lineWidth = _a.lineWidth, lineHeight = _a.lineHeight;
  207. this.getRect('.van-tab', true).then(function (rects) {
  208. if (rects === void 0) { rects = []; }
  209. var rect = rects[currentIndex];
  210. if (rect == null) {
  211. return;
  212. }
  213. var width = lineWidth !== -1 ? lineWidth : rect.width / 2;
  214. var height = lineHeight !== -1
  215. ? "height: " + utils_1.addUnit(lineHeight) + "; border-radius: " + utils_1.addUnit(lineHeight) + ";"
  216. : '';
  217. var left = rects
  218. .slice(0, currentIndex)
  219. .reduce(function (prev, curr) { return prev + curr.width; }, 0);
  220. left += (rect.width - width) / 2;
  221. var transition = skipTransition
  222. ? ''
  223. : "transition-duration: " + duration + "s; -webkit-transition-duration: " + duration + "s;";
  224. _this.setData({
  225. lineStyle: "\n " + height + "\n width: " + utils_1.addUnit(width) + ";\n background-color: " + color + ";\n -webkit-transform: translateX(" + left + "px);\n transform: translateX(" + left + "px);\n " + transition + "\n "
  226. });
  227. });
  228. },
  229. // scroll active tab into view
  230. scrollIntoView: function () {
  231. var _this = this;
  232. var _a = this.data, currentIndex = _a.currentIndex, scrollable = _a.scrollable;
  233. if (!scrollable) {
  234. return;
  235. }
  236. Promise.all([
  237. this.getRect('.van-tab', true),
  238. this.getRect('.van-tabs__nav')
  239. ]).then(function (_a) {
  240. var tabRects = _a[0], navRect = _a[1];
  241. var tabRect = tabRects[currentIndex];
  242. var offsetLeft = tabRects
  243. .slice(0, currentIndex)
  244. .reduce(function (prev, curr) { return prev + curr.width; }, 0);
  245. _this.setData({
  246. scrollLeft: offsetLeft - (navRect.width - tabRect.width) / 2
  247. });
  248. });
  249. },
  250. onTouchScroll: function (event) {
  251. this.$emit('scroll', event.detail);
  252. },
  253. onTouchStart: function (event) {
  254. if (!this.data.swipeable)
  255. return;
  256. this.touchStart(event);
  257. },
  258. onTouchMove: function (event) {
  259. if (!this.data.swipeable)
  260. return;
  261. this.touchMove(event);
  262. },
  263. // watch swipe touch end
  264. onTouchEnd: function () {
  265. if (!this.data.swipeable)
  266. return;
  267. var _a = this.data, tabs = _a.tabs, currentIndex = _a.currentIndex;
  268. var _b = this, direction = _b.direction, deltaX = _b.deltaX, offsetX = _b.offsetX;
  269. var minSwipeDistance = 50;
  270. if (direction === 'horizontal' && offsetX >= minSwipeDistance) {
  271. if (deltaX > 0 && currentIndex !== 0) {
  272. this.setCurrentIndex(currentIndex - 1);
  273. }
  274. else if (deltaX < 0 && currentIndex !== tabs.length - 1) {
  275. this.setCurrentIndex(currentIndex + 1);
  276. }
  277. }
  278. }
  279. }
  280. });