项目原始demo,不改动
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
 
 
 
 

426 lines
10 KiB

  1. // Helpers
  2. import { wrapInArray, sortItems, deepEqual, groupItems, searchItems, fillArray } from '../../util/helpers';
  3. import Vue from 'vue';
  4. export default Vue.extend({
  5. name: 'v-data',
  6. inheritAttrs: false,
  7. props: {
  8. items: {
  9. type: Array,
  10. default: () => []
  11. },
  12. options: {
  13. type: Object,
  14. default: () => ({})
  15. },
  16. sortBy: {
  17. type: [String, Array],
  18. default: () => []
  19. },
  20. sortDesc: {
  21. type: [Boolean, Array],
  22. default: () => []
  23. },
  24. customSort: {
  25. type: Function,
  26. default: sortItems
  27. },
  28. mustSort: Boolean,
  29. multiSort: Boolean,
  30. page: {
  31. type: Number,
  32. default: 1
  33. },
  34. itemsPerPage: {
  35. type: Number,
  36. default: 10
  37. },
  38. groupBy: {
  39. type: [String, Array],
  40. default: () => []
  41. },
  42. groupDesc: {
  43. type: [Boolean, Array],
  44. default: () => []
  45. },
  46. customGroup: {
  47. type: Function,
  48. default: groupItems
  49. },
  50. locale: {
  51. type: String,
  52. default: 'en-US'
  53. },
  54. disableSort: Boolean,
  55. disablePagination: Boolean,
  56. disableFiltering: Boolean,
  57. search: String,
  58. customFilter: {
  59. type: Function,
  60. default: searchItems
  61. },
  62. serverItemsLength: {
  63. type: Number,
  64. default: -1
  65. }
  66. },
  67. data() {
  68. let internalOptions = {
  69. page: this.page,
  70. itemsPerPage: this.itemsPerPage,
  71. sortBy: wrapInArray(this.sortBy),
  72. sortDesc: wrapInArray(this.sortDesc),
  73. groupBy: wrapInArray(this.groupBy),
  74. groupDesc: wrapInArray(this.groupDesc),
  75. mustSort: this.mustSort,
  76. multiSort: this.multiSort
  77. };
  78. if (this.options) {
  79. internalOptions = Object.assign(internalOptions, this.options);
  80. }
  81. const {
  82. sortBy,
  83. sortDesc,
  84. groupBy,
  85. groupDesc
  86. } = internalOptions;
  87. const sortDiff = sortBy.length - sortDesc.length;
  88. const groupDiff = groupBy.length - groupDesc.length;
  89. if (sortDiff > 0) {
  90. internalOptions.sortDesc.push(...fillArray(sortDiff, false));
  91. }
  92. if (groupDiff > 0) {
  93. internalOptions.groupDesc.push(...fillArray(groupDiff, false));
  94. }
  95. return {
  96. internalOptions
  97. };
  98. },
  99. computed: {
  100. itemsLength() {
  101. return this.serverItemsLength >= 0 ? this.serverItemsLength : this.filteredItems.length;
  102. },
  103. pageCount() {
  104. return this.internalOptions.itemsPerPage <= 0 ? 1 : Math.ceil(this.itemsLength / this.internalOptions.itemsPerPage);
  105. },
  106. pageStart() {
  107. if (this.internalOptions.itemsPerPage === -1 || !this.items.length) return 0;
  108. return (this.internalOptions.page - 1) * this.internalOptions.itemsPerPage;
  109. },
  110. pageStop() {
  111. if (this.internalOptions.itemsPerPage === -1) return this.itemsLength;
  112. if (!this.items.length) return 0;
  113. return Math.min(this.itemsLength, this.internalOptions.page * this.internalOptions.itemsPerPage);
  114. },
  115. isGrouped() {
  116. return !!this.internalOptions.groupBy.length;
  117. },
  118. pagination() {
  119. return {
  120. page: this.internalOptions.page,
  121. itemsPerPage: this.internalOptions.itemsPerPage,
  122. pageStart: this.pageStart,
  123. pageStop: this.pageStop,
  124. pageCount: this.pageCount,
  125. itemsLength: this.itemsLength
  126. };
  127. },
  128. filteredItems() {
  129. let items = this.items.slice();
  130. if (!this.disableFiltering && this.serverItemsLength <= 0) {
  131. items = this.customFilter(items, this.search);
  132. }
  133. return items;
  134. },
  135. computedItems() {
  136. let items = this.filteredItems.slice();
  137. if (!this.disableSort && this.serverItemsLength <= 0) {
  138. items = this.sortItems(items);
  139. }
  140. if (!this.disablePagination && this.serverItemsLength <= 0) {
  141. items = this.paginateItems(items);
  142. }
  143. return items;
  144. },
  145. groupedItems() {
  146. return this.isGrouped ? this.groupItems(this.computedItems) : null;
  147. },
  148. scopedProps() {
  149. const props = {
  150. sort: this.sort,
  151. sortArray: this.sortArray,
  152. group: this.group,
  153. items: this.computedItems,
  154. options: this.internalOptions,
  155. updateOptions: this.updateOptions,
  156. pagination: this.pagination,
  157. groupedItems: this.groupedItems,
  158. originalItemsLength: this.items.length
  159. };
  160. return props;
  161. },
  162. computedOptions() {
  163. return { ...this.options
  164. };
  165. }
  166. },
  167. watch: {
  168. computedOptions: {
  169. handler(options, old) {
  170. if (deepEqual(options, old)) return;
  171. this.updateOptions(options);
  172. },
  173. deep: true,
  174. immediate: true
  175. },
  176. internalOptions: {
  177. handler(options, old) {
  178. if (deepEqual(options, old)) return;
  179. this.$emit('update:options', options);
  180. },
  181. deep: true,
  182. immediate: true
  183. },
  184. page(page) {
  185. this.updateOptions({
  186. page
  187. });
  188. },
  189. 'internalOptions.page'(page) {
  190. this.$emit('update:page', page);
  191. },
  192. itemsPerPage(itemsPerPage) {
  193. this.updateOptions({
  194. itemsPerPage
  195. });
  196. },
  197. 'internalOptions.itemsPerPage'(itemsPerPage) {
  198. this.$emit('update:items-per-page', itemsPerPage);
  199. },
  200. sortBy(sortBy) {
  201. this.updateOptions({
  202. sortBy: wrapInArray(sortBy)
  203. });
  204. },
  205. 'internalOptions.sortBy'(sortBy, old) {
  206. !deepEqual(sortBy, old) && this.$emit('update:sort-by', Array.isArray(this.sortBy) ? sortBy : sortBy[0]);
  207. },
  208. sortDesc(sortDesc) {
  209. this.updateOptions({
  210. sortDesc: wrapInArray(sortDesc)
  211. });
  212. },
  213. 'internalOptions.sortDesc'(sortDesc, old) {
  214. !deepEqual(sortDesc, old) && this.$emit('update:sort-desc', Array.isArray(this.sortDesc) ? sortDesc : sortDesc[0]);
  215. },
  216. groupBy(groupBy) {
  217. this.updateOptions({
  218. groupBy: wrapInArray(groupBy)
  219. });
  220. },
  221. 'internalOptions.groupBy'(groupBy, old) {
  222. !deepEqual(groupBy, old) && this.$emit('update:group-by', Array.isArray(this.groupBy) ? groupBy : groupBy[0]);
  223. },
  224. groupDesc(groupDesc) {
  225. this.updateOptions({
  226. groupDesc: wrapInArray(groupDesc)
  227. });
  228. },
  229. 'internalOptions.groupDesc'(groupDesc, old) {
  230. !deepEqual(groupDesc, old) && this.$emit('update:group-desc', Array.isArray(this.groupDesc) ? groupDesc : groupDesc[0]);
  231. },
  232. multiSort(multiSort) {
  233. this.updateOptions({
  234. multiSort
  235. });
  236. },
  237. 'internalOptions.multiSort'(multiSort) {
  238. this.$emit('update:multi-sort', multiSort);
  239. },
  240. mustSort(mustSort) {
  241. this.updateOptions({
  242. mustSort
  243. });
  244. },
  245. 'internalOptions.mustSort'(mustSort) {
  246. this.$emit('update:must-sort', mustSort);
  247. },
  248. pageCount: {
  249. handler(pageCount) {
  250. this.$emit('page-count', pageCount);
  251. },
  252. immediate: true
  253. },
  254. computedItems: {
  255. handler(computedItems) {
  256. this.$emit('current-items', computedItems);
  257. },
  258. immediate: true
  259. },
  260. pagination: {
  261. handler(pagination, old) {
  262. if (deepEqual(pagination, old)) return;
  263. this.$emit('pagination', this.pagination);
  264. },
  265. immediate: true
  266. }
  267. },
  268. methods: {
  269. toggle(key, oldBy, oldDesc, page, mustSort, multiSort) {
  270. let by = oldBy.slice();
  271. let desc = oldDesc.slice();
  272. const byIndex = by.findIndex(k => k === key);
  273. if (byIndex < 0) {
  274. if (!multiSort) {
  275. by = [];
  276. desc = [];
  277. }
  278. by.push(key);
  279. desc.push(false);
  280. } else if (byIndex >= 0 && !desc[byIndex]) {
  281. desc[byIndex] = true;
  282. } else if (!mustSort) {
  283. by.splice(byIndex, 1);
  284. desc.splice(byIndex, 1);
  285. } else {
  286. desc[byIndex] = false;
  287. } // Reset page to 1 if sortBy or sortDesc have changed
  288. if (!deepEqual(by, oldBy) || !deepEqual(desc, oldDesc)) {
  289. page = 1;
  290. }
  291. return {
  292. by,
  293. desc,
  294. page
  295. };
  296. },
  297. group(key) {
  298. const {
  299. by: groupBy,
  300. desc: groupDesc,
  301. page
  302. } = this.toggle(key, this.internalOptions.groupBy, this.internalOptions.groupDesc, this.internalOptions.page, true, false);
  303. this.updateOptions({
  304. groupBy,
  305. groupDesc,
  306. page
  307. });
  308. },
  309. sort(key) {
  310. if (Array.isArray(key)) return this.sortArray(key);
  311. const {
  312. by: sortBy,
  313. desc: sortDesc,
  314. page
  315. } = this.toggle(key, this.internalOptions.sortBy, this.internalOptions.sortDesc, this.internalOptions.page, this.internalOptions.mustSort, this.internalOptions.multiSort);
  316. this.updateOptions({
  317. sortBy,
  318. sortDesc,
  319. page
  320. });
  321. },
  322. sortArray(sortBy) {
  323. const sortDesc = sortBy.map(s => {
  324. const i = this.internalOptions.sortBy.findIndex(k => k === s);
  325. return i > -1 ? this.internalOptions.sortDesc[i] : false;
  326. });
  327. this.updateOptions({
  328. sortBy,
  329. sortDesc
  330. });
  331. },
  332. updateOptions(options) {
  333. this.internalOptions = { ...this.internalOptions,
  334. ...options,
  335. page: this.serverItemsLength < 0 ? Math.max(1, Math.min(options.page || this.internalOptions.page, this.pageCount)) : options.page || this.internalOptions.page
  336. };
  337. },
  338. sortItems(items) {
  339. let sortBy = this.internalOptions.sortBy;
  340. let sortDesc = this.internalOptions.sortDesc;
  341. if (this.internalOptions.groupBy.length) {
  342. sortBy = [...this.internalOptions.groupBy, ...sortBy];
  343. sortDesc = [...this.internalOptions.groupDesc, ...sortDesc];
  344. }
  345. return this.customSort(items, sortBy, sortDesc, this.locale);
  346. },
  347. groupItems(items) {
  348. return this.customGroup(items, this.internalOptions.groupBy, this.internalOptions.groupDesc);
  349. },
  350. paginateItems(items) {
  351. // Make sure we don't try to display non-existant page if items suddenly change
  352. // TODO: Could possibly move this to pageStart/pageStop?
  353. if (this.serverItemsLength === -1 && items.length <= this.pageStart) {
  354. this.internalOptions.page = Math.max(1, this.internalOptions.page - 1);
  355. }
  356. return items.slice(this.pageStart, this.pageStop);
  357. }
  358. },
  359. render() {
  360. return this.$scopedSlots.default && this.$scopedSlots.default(this.scopedProps);
  361. }
  362. });
  363. //# sourceMappingURL=VData.js.map