list.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. var _xeUtils = _interopRequireDefault(require("xe-utils"));
  7. var _conf = _interopRequireDefault(require("../../v-x-e-table/src/conf"));
  8. var _size = _interopRequireDefault(require("../../mixins/size"));
  9. var _tools = require("../../tools");
  10. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  11. var browse = _tools.DomTools.browse;
  12. var _default2 = {
  13. name: 'VxeList',
  14. mixins: [_size.default],
  15. props: {
  16. data: Array,
  17. height: [Number, String],
  18. maxHeight: [Number, String],
  19. loading: Boolean,
  20. size: {
  21. type: String,
  22. default: function _default() {
  23. return _conf.default.list.size || _conf.default.size;
  24. }
  25. },
  26. autoResize: {
  27. type: Boolean,
  28. default: function _default() {
  29. return _conf.default.list.autoResize;
  30. }
  31. },
  32. syncResize: [Boolean, String, Number],
  33. scrollY: Object
  34. },
  35. data: function data() {
  36. return {
  37. scrollYLoad: false,
  38. bodyHeight: 0,
  39. topSpaceHeight: 0,
  40. items: []
  41. };
  42. },
  43. computed: {
  44. sYOpts: function sYOpts() {
  45. return Object.assign({}, _conf.default.list.scrollY, this.scrollY);
  46. },
  47. styles: function styles() {
  48. var height = this.height,
  49. maxHeight = this.maxHeight;
  50. var style = {};
  51. if (height) {
  52. style.height = isNaN(height) ? height : "".concat(height, "px");
  53. } else if (maxHeight) {
  54. style.height = 'auto';
  55. style.maxHeight = isNaN(maxHeight) ? maxHeight : "".concat(maxHeight, "px");
  56. }
  57. return style;
  58. }
  59. },
  60. watch: {
  61. data: function data(value) {
  62. this.loadData(value);
  63. },
  64. syncResize: function syncResize(value) {
  65. var _this = this;
  66. if (value) {
  67. this.recalculate();
  68. this.$nextTick(function () {
  69. return setTimeout(function () {
  70. return _this.recalculate();
  71. });
  72. });
  73. }
  74. }
  75. },
  76. created: function created() {
  77. Object.assign(this, {
  78. fullData: [],
  79. lastScrollLeft: 0,
  80. lastScrollTop: 0,
  81. scrollYStore: {
  82. startIndex: 0,
  83. endIndex: 0,
  84. visibleSize: 0
  85. }
  86. });
  87. this.loadData(this.data);
  88. _tools.GlobalEvent.on(this, 'resize', this.handleGlobalResizeEvent);
  89. },
  90. mounted: function mounted() {
  91. var _this2 = this;
  92. if (this.autoResize) {
  93. var resizeObserver = (0, _tools.createResizeEvent)(function () {
  94. return _this2.recalculate();
  95. });
  96. resizeObserver.observe(this.$el);
  97. this.$resize = resizeObserver;
  98. }
  99. },
  100. beforeDestroy: function beforeDestroy() {
  101. if (this.$resize) {
  102. this.$resize.disconnect();
  103. }
  104. },
  105. destroyed: function destroyed() {
  106. _tools.GlobalEvent.off(this, 'resize');
  107. },
  108. render: function render(h) {
  109. var $scopedSlots = this.$scopedSlots,
  110. styles = this.styles,
  111. bodyHeight = this.bodyHeight,
  112. topSpaceHeight = this.topSpaceHeight,
  113. items = this.items,
  114. loading = this.loading;
  115. return h('div', {
  116. class: ['vxe-list', {
  117. 'is--loading': loading
  118. }]
  119. }, [h('div', {
  120. ref: 'virtualWrapper',
  121. class: 'vxe-list--virtual-wrapper',
  122. style: styles,
  123. on: {
  124. scroll: this.scrollEvent
  125. }
  126. }, [h('div', {
  127. ref: 'ySpace',
  128. class: 'vxe-list--y-space',
  129. style: {
  130. height: bodyHeight ? "".concat(bodyHeight, "px") : ''
  131. }
  132. }), h('div', {
  133. ref: 'body',
  134. class: 'vxe-list--body',
  135. style: {
  136. marginTop: topSpaceHeight ? "".concat(topSpaceHeight, "px") : ''
  137. }
  138. }, $scopedSlots.default ? $scopedSlots.default.call(this, {
  139. items: items,
  140. $list: this
  141. }, h) : [])]), h('div', {
  142. class: ['vxe-list--loading vxe-loading', {
  143. 'is--visible': loading
  144. }]
  145. }, [h('div', {
  146. class: 'vxe-loading--spinner'
  147. })])]);
  148. },
  149. methods: {
  150. getParentElem: function getParentElem() {
  151. return this.$el.parentNode;
  152. },
  153. /**
  154. * 加载数据
  155. * @param {Array} datas 数据
  156. */
  157. loadData: function loadData(datas) {
  158. var _this3 = this;
  159. var sYOpts = this.sYOpts,
  160. scrollYStore = this.scrollYStore;
  161. var fullData = datas || [];
  162. scrollYStore.startIndex = 0;
  163. scrollYStore.visibleIndex = 0;
  164. this.fullData = fullData;
  165. this.scrollYLoad = sYOpts.enabled && sYOpts.gt > -1 && sYOpts.gt <= fullData.length;
  166. this.handleData();
  167. return this.computeScrollLoad().then(function () {
  168. _this3.refreshScroll();
  169. });
  170. },
  171. /**
  172. * 重新加载数据
  173. * @param {Array} datas 数据
  174. */
  175. reloadData: function reloadData(datas) {
  176. this.clearScroll();
  177. return this.loadData(datas);
  178. },
  179. handleData: function handleData() {
  180. var fullData = this.fullData,
  181. scrollYLoad = this.scrollYLoad,
  182. scrollYStore = this.scrollYStore;
  183. this.items = scrollYLoad ? fullData.slice(scrollYStore.startIndex, scrollYStore.endIndex) : fullData.slice(0);
  184. return this.$nextTick();
  185. },
  186. /**
  187. * 重新计算列表
  188. */
  189. recalculate: function recalculate() {
  190. var $el = this.$el;
  191. if ($el.clientWidth && $el.clientHeight) {
  192. return this.computeScrollLoad();
  193. }
  194. return Promise.resolve();
  195. },
  196. /**
  197. * 清除滚动条
  198. */
  199. clearScroll: function clearScroll() {
  200. var _this4 = this;
  201. var scrollBodyElem = this.$refs.virtualWrapper;
  202. if (scrollBodyElem) {
  203. scrollBodyElem.scrollTop = 0;
  204. }
  205. return new Promise(function (resolve) {
  206. setTimeout(function () {
  207. resolve(_this4.$nextTick());
  208. });
  209. });
  210. },
  211. /**
  212. * 刷新滚动条
  213. */
  214. refreshScroll: function refreshScroll() {
  215. var _this5 = this;
  216. var lastScrollLeft = this.lastScrollLeft,
  217. lastScrollTop = this.lastScrollTop;
  218. return this.clearScroll().then(function () {
  219. if (lastScrollLeft || lastScrollTop) {
  220. _this5.lastScrollLeft = 0;
  221. _this5.lastScrollTop = 0;
  222. return _this5.scrollTo(lastScrollLeft, lastScrollTop);
  223. }
  224. });
  225. },
  226. /**
  227. * 如果有滚动条,则滚动到对应的位置
  228. * @param {Number} scrollLeft 左距离
  229. * @param {Number} scrollTop 上距离
  230. */
  231. scrollTo: function scrollTo(scrollLeft, scrollTop) {
  232. var _this6 = this;
  233. var scrollBodyElem = this.$refs.virtualWrapper;
  234. if (_xeUtils.default.isNumber(scrollLeft)) {
  235. scrollBodyElem.scrollLeft = scrollLeft;
  236. }
  237. if (_xeUtils.default.isNumber(scrollTop)) {
  238. scrollBodyElem.scrollTop = scrollTop;
  239. }
  240. if (this.scrollYLoad) {
  241. return new Promise(function (resolve) {
  242. return setTimeout(function () {
  243. return resolve(_this6.$nextTick());
  244. }, 50);
  245. });
  246. }
  247. return this.$nextTick();
  248. },
  249. computeScrollLoad: function computeScrollLoad() {
  250. var _this7 = this;
  251. return this.$nextTick().then(function () {
  252. var $refs = _this7.$refs,
  253. sYOpts = _this7.sYOpts,
  254. scrollYLoad = _this7.scrollYLoad,
  255. scrollYStore = _this7.scrollYStore;
  256. var rowHeight = 0;
  257. var firstItemElem;
  258. if (sYOpts.sItem) {
  259. firstItemElem = $refs.body.querySelector(sYOpts.sItem);
  260. }
  261. if (!firstItemElem) {
  262. firstItemElem = $refs.body.children[0];
  263. }
  264. if (firstItemElem) {
  265. rowHeight = firstItemElem.offsetHeight;
  266. }
  267. rowHeight = Math.max(20, rowHeight);
  268. scrollYStore.rowHeight = rowHeight; // 计算 Y 逻辑
  269. if (scrollYLoad) {
  270. var visibleYSize = Math.max(8, Math.ceil($refs.virtualWrapper.clientHeight / rowHeight));
  271. var offsetYSize = sYOpts.oSize ? _xeUtils.default.toNumber(sYOpts.oSize) : browse.msie ? 20 : browse.edge ? 10 : 0;
  272. scrollYStore.offsetSize = offsetYSize;
  273. scrollYStore.visibleSize = visibleYSize;
  274. scrollYStore.endIndex = Math.max(scrollYStore.startIndex, visibleYSize + offsetYSize, scrollYStore.endIndex);
  275. _this7.updateYData();
  276. } else {
  277. _this7.updateYSpace();
  278. }
  279. _this7.rowHeight = rowHeight;
  280. });
  281. },
  282. scrollEvent: function scrollEvent(evnt) {
  283. var scrollBodyElem = evnt.target;
  284. var scrollTop = scrollBodyElem.scrollTop;
  285. var scrollLeft = scrollBodyElem.scrollLeft;
  286. var isX = scrollLeft !== this.lastScrollLeft;
  287. var isY = scrollTop !== this.lastScrollTop;
  288. this.lastScrollTop = scrollTop;
  289. this.lastScrollLeft = scrollLeft;
  290. if (this.scrollYLoad) {
  291. this.loadYData(evnt);
  292. }
  293. this.$emit('scroll', {
  294. scrollLeft: scrollLeft,
  295. scrollTop: scrollTop,
  296. isX: isX,
  297. isY: isY,
  298. $event: evnt
  299. });
  300. },
  301. loadYData: function loadYData(evnt) {
  302. var scrollYStore = this.scrollYStore;
  303. var startIndex = scrollYStore.startIndex,
  304. endIndex = scrollYStore.endIndex,
  305. visibleSize = scrollYStore.visibleSize,
  306. offsetSize = scrollYStore.offsetSize,
  307. rowHeight = scrollYStore.rowHeight;
  308. var scrollBodyElem = evnt.target;
  309. var scrollTop = scrollBodyElem.scrollTop;
  310. var toVisibleIndex = Math.floor(scrollTop / rowHeight);
  311. var offsetStartIndex = Math.max(0, toVisibleIndex - 1 - offsetSize);
  312. var offsetEndIndex = toVisibleIndex + visibleSize + offsetSize;
  313. if (toVisibleIndex <= startIndex || toVisibleIndex >= endIndex - visibleSize - 1) {
  314. if (startIndex !== offsetStartIndex || endIndex !== offsetEndIndex) {
  315. scrollYStore.startIndex = offsetStartIndex;
  316. scrollYStore.endIndex = offsetEndIndex;
  317. this.updateYData();
  318. }
  319. }
  320. },
  321. updateYData: function updateYData() {
  322. this.handleData();
  323. this.updateYSpace();
  324. },
  325. updateYSpace: function updateYSpace() {
  326. var scrollYStore = this.scrollYStore,
  327. scrollYLoad = this.scrollYLoad,
  328. fullData = this.fullData;
  329. this.bodyHeight = scrollYLoad ? fullData.length * scrollYStore.rowHeight : 0;
  330. this.topSpaceHeight = scrollYLoad ? Math.max(scrollYStore.startIndex * scrollYStore.rowHeight, 0) : 0;
  331. },
  332. handleGlobalResizeEvent: function handleGlobalResizeEvent() {
  333. this.recalculate();
  334. }
  335. }
  336. };
  337. exports.default = _default2;