123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- /**
- * 瀑布流组件
- */
- Component({
- properties: {
- intervalWidth: {
- type: String,
- value: "20rpx"
- }
- },
- data: {
- items: [],
- stopMasonry: false
- },
- methods: {
- /**
- * 批量添加元素
- *
- * @param {Array} items - 新增的元素数组
- */
- append(items) {
- if (Object.prototype.toString.call(items) !=='[object Array]') {
- console.error("[masonry]参数类型错误,渲染失败");
- return false;
- }
- this.setData({
- stopMasonry: false
- })
-
- return this._refresh(items);
- },
- /**
- * 批量删除瀑布流中的元素
- *
- * @param {Number} start - 开始下标
- * @param {Number} end - 结束下标
- */
- delete(start, end) {
- const { items } = this.data;
- if (start < end && start < items.length - 1) {
- let len = end- start;
- let newItems = items.splice(start, len);
- this._refresh(newItems)
- } else {
- console.error("[masonry]初始下标异常,删除失败!");
- }
- },
- /**
- * 更新数组中的某个元素
- *
- * @param {Object} newItem - 修改后的元素
- * @param {Number} index - 需要更新的数组下标
- */
- updateItem(newItem, index) {
- const { items } = this.data;
- if (index <= items.length - 1) {
- this.setData({
- items: [
- ...items.slice(0, index),
- Object.assign(items[index], newItem),
- ...items.slice(index + 1)
- ]
- })
- } else {
- console.error("[masonry]下标越界,修改失败!");
- }
- },
- /**
- * 删除瀑布流中的某个元素
- *
- * @param {Number} index - 数组下标
- */
- deleteItem(index) {
- const { items } = this.data;
- if (index <= items.length - 1) {
- let newItems = items.splice(index, 1);
- this._refresh(newItems)
- } else {
- console.error("[masonry]下标越界,删除失败!");
- }
- },
- /**
- * 刷新瀑布流
- *
- * @param {Array} items - 参与渲染的元素数组
- */
- start(items) {
- if (Object.prototype.toString.call(items) !=='[object Array]') {
- console.error("[masonry]参数类型错误,渲染失败");
- return false;
- }
-
- this.setData({
- items: [],
- stopMasonry: false
- })
- return this._refresh(items);
- },
- /**
- * 停止渲染瀑布流
- */
- stop() {
- this.setData({
- stopMasonry: true,
- items: []
- })
- },
- /**
- * 刷新瀑布流
- *
- * @param {Array} items - 参与渲染的元素数组
- */
- _refresh(items) {
- const query = wx.createSelectorQuery().in(this)
- this.columnNodes = query.selectAll('#left-col-inner, #right-col-inner')
- return new Promise((resolve, reject) => {
- this._render(items, 0, () => {
- resolve()
- })
- })
- },
- /**
- * 渲染函数
- *
- * @param {Array} items - 正在渲染的数组
- * @param {Number} i - 当前渲染元素的下标
- * @param {Function} onComplete - 完成后的回调函数
- */
- _render (items, i, onComplete) {
- if (items.length > i && !this.data.stopMasonry) {
- this.columnNodes.boundingClientRect().exec(arr => {
- const item = items[i]
- const rects = arr[0]
- const leftColHeight = rects[0].height
- const rightColHeight = rects[1].height
- this.setData({
- items: [...this.data.items, {
- ...item,
- columnPosition: leftColHeight <= rightColHeight ? 'left' : 'right'
- }]
- }, () => {
- this._render(items, ++i, onComplete)
- })
- })
- } else {
- onComplete && onComplete()
- }
- },
-
- needAuth: function () {
- this.triggerEvent('needAuth');
- }
- }
- });
|