Skip to content

Commit 5503a7f

Browse files
author
He Feixiang
committed
build project
0 parents  commit 5503a7f

18 files changed

+2189
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# mpMasonry

app.js

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//app.js
2+
App({
3+
onLaunch: function () {
4+
// 展示本地存储能力
5+
var logs = wx.getStorageSync('logs') || []
6+
logs.unshift(Date.now())
7+
wx.setStorageSync('logs', logs)
8+
9+
// 登录
10+
wx.login({
11+
success: res => {
12+
// 发送 res.code 到后台换取 openId, sessionKey, unionId
13+
}
14+
})
15+
// 获取用户信息
16+
wx.getSetting({
17+
success: res => {
18+
if (res.authSetting['scope.userInfo']) {
19+
// 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
20+
wx.getUserInfo({
21+
success: res => {
22+
// 可以将 res 发送给后台解码出 unionId
23+
this.globalData.userInfo = res.userInfo
24+
25+
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
26+
// 所以此处加入 callback 以防止这种情况
27+
if (this.userInfoReadyCallback) {
28+
this.userInfoReadyCallback(res)
29+
}
30+
}
31+
})
32+
}
33+
}
34+
})
35+
},
36+
globalData: {
37+
userInfo: null
38+
}
39+
})

app.json

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"pages":[
3+
"pages/index/index"
4+
],
5+
"window":{
6+
"backgroundTextStyle":"light",
7+
"navigationBarBackgroundColor": "#fff",
8+
"navigationBarTitleText": "WeChat",
9+
"navigationBarTextStyle":"black"
10+
}
11+
}

app.wxss

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**app.wxss**/
2+
.container {
3+
height: 100%;
4+
display: flex;
5+
flex-direction: column;
6+
align-items: center;
7+
justify-content: space-between;
8+
box-sizing: border-box;
9+
padding: 0 20rpx;
10+
}

components/img-box/img-box.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Component({
2+
properties: {
3+
item: {
4+
type: String,
5+
value: ''
6+
}
7+
}
8+
})

components/img-box/img-box.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"component": true
3+
}
4+

components/img-box/img-box.wxml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<view class="img-box">
2+
<image src="{{item.images_list[0].url}}"></image>
3+
<text>{{item.name}}</text>
4+
</view>

components/img-box/img-box.wxss

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
.img-box{
2+
width: 100%;
3+
margin-bottom: 20px;
4+
}
5+
.img-box image{
6+
display: block;
7+
width: 100%;
8+
}
9+
.img-box text{
10+
font-size: 28rpx;
11+
line-height: 1;
12+
}

components/masonry/masonry.js

+161
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/**
2+
* 瀑布流组件
3+
*/
4+
Component({
5+
properties: {
6+
intervalWidth: {
7+
type: String,
8+
value: "20rpx"
9+
}
10+
},
11+
data: {
12+
items: [],
13+
stopMasonry: false
14+
},
15+
methods: {
16+
/**
17+
* 批量添加元素
18+
*
19+
* @param {Array} items - 新增的元素数组
20+
*/
21+
append(items) {
22+
if (Object.prototype.toString.call(items) !=='[object Array]') {
23+
console.error("[masonry]参数类型错误,渲染失败");
24+
return false;
25+
}
26+
27+
this.setData({
28+
stopMasonry: false
29+
})
30+
31+
return this._refresh(items);
32+
},
33+
34+
/**
35+
* 批量删除瀑布流中的元素
36+
*
37+
* @param {Number} start - 开始下标
38+
* @param {Number} end - 结束下标
39+
*/
40+
delete(start, end) {
41+
const { items } = this.data;
42+
if (start < end && start < items.length - 1) {
43+
let len = end- start;
44+
let newItems = items.splice(start, len);
45+
this._refresh(newItems)
46+
} else {
47+
console.error("[masonry]初始下标异常,删除失败!");
48+
}
49+
},
50+
51+
/**
52+
* 更新数组中的某个元素
53+
*
54+
* @param {Object} newItem - 修改后的元素
55+
* @param {Number} index - 需要更新的数组下标
56+
*/
57+
updateItem(newItem, index) {
58+
const { items } = this.data;
59+
if (index <= items.length - 1) {
60+
this.setData({
61+
items: [
62+
...items.slice(0, index),
63+
Object.assign(items[index], newItem),
64+
...items.slice(index + 1)
65+
]
66+
})
67+
} else {
68+
console.error("[masonry]下标越界,修改失败!");
69+
}
70+
},
71+
72+
/**
73+
* 删除瀑布流中的某个元素
74+
*
75+
* @param {Number} index - 数组下标
76+
*/
77+
deleteItem(index) {
78+
const { items } = this.data;
79+
if (index <= items.length - 1) {
80+
let newItems = items.splice(index, 1);
81+
this._refresh(newItems)
82+
} else {
83+
console.error("[masonry]下标越界,删除失败!");
84+
}
85+
},
86+
87+
/**
88+
* 刷新瀑布流
89+
*
90+
* @param {Array} items - 参与渲染的元素数组
91+
*/
92+
start(items) {
93+
if (Object.prototype.toString.call(items) !=='[object Array]') {
94+
console.error("[masonry]参数类型错误,渲染失败");
95+
return false;
96+
}
97+
98+
this.setData({
99+
items: [],
100+
stopMasonry: false
101+
})
102+
103+
return this._refresh(items);
104+
},
105+
106+
/**
107+
* 停止渲染瀑布流
108+
*/
109+
stop() {
110+
this.setData({
111+
stopMasonry: true,
112+
items: []
113+
})
114+
},
115+
116+
/**
117+
* 刷新瀑布流
118+
*
119+
* @param {Array} items - 参与渲染的元素数组
120+
*/
121+
_refresh(items) {
122+
const query = wx.createSelectorQuery().in(this)
123+
this.columnNodes = query.selectAll('#left-col-inner, #right-col-inner')
124+
125+
return new Promise((resolve, reject) => {
126+
this._render(items, 0, () => {
127+
resolve()
128+
})
129+
})
130+
},
131+
132+
/**
133+
* 渲染函数
134+
*
135+
* @param {Array} items - 正在渲染的数组
136+
* @param {Number} i - 当前渲染元素的下标
137+
* @param {Function} onComplete - 完成后的回调函数
138+
*/
139+
_render (items, i, onComplete) {
140+
if (items.length > i && !this.data.stopMasonry) {
141+
this.columnNodes.boundingClientRect().exec(arr => {
142+
const item = items[i]
143+
const rects = arr[0]
144+
const leftColHeight = rects[0].height
145+
const rightColHeight = rects[1].height
146+
147+
this.setData({
148+
items: [...this.data.items, {
149+
...item,
150+
columnPosition: leftColHeight <= rightColHeight ? 'left' : 'right'
151+
}]
152+
}, () => {
153+
this._render(items, ++i, onComplete)
154+
})
155+
})
156+
} else {
157+
onComplete && onComplete()
158+
}
159+
}
160+
}
161+
});

components/masonry/masonry.json

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"component": true,
3+
"componentGenerics": {
4+
"masonry-item": true
5+
}
6+
}

components/masonry/masonry.wxml

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<view class="masonry-list">
2+
<view class="masonry-list-left" style="{{ 'margin-right:' + intervalWidth }}">
3+
<view id="left-col-inner">
4+
<block wx:for="{{items}}" wx:key="{{item.id}}">
5+
<masonry-item wx:if="{{item.columnPosition === 'left'}}" item="{{item}}"></masonry-item>
6+
</block>
7+
</view>
8+
</view>
9+
<view class="masonry-list-right">
10+
<view id="right-col-inner">
11+
<block wx:for="{{items}}" wx:key="{{item.id}}">
12+
<masonry-item wx:if="{{item.columnPosition === 'right'}}" item="{{item}}"></masonry-item>
13+
</block>
14+
</view>
15+
</view>
16+
</view>

components/masonry/masonry.wxss

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.masonry-list {
2+
width: 100%;
3+
display: flex;
4+
box-sizing: border-box;
5+
}
6+
7+
.masonry-list-left, .masonry-list-right {
8+
flex: 1;
9+
display: flex;
10+
flex-direction: column;
11+
}

pages/index/index.js

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//index.js
2+
//获取应用实例
3+
const app = getApp()
4+
5+
import mock from './mock.js'
6+
7+
Page({
8+
data: {
9+
items: mock
10+
},
11+
12+
onLoad: function () {
13+
this._doRefreshMasonry(this.data.items)
14+
},
15+
16+
onReachBottom: function () {
17+
this._doAppendMasonry(this.data.items)
18+
},
19+
20+
_doRefreshMasonry(items) {
21+
this.masonryListComponent = this.selectComponent('#masonry');
22+
this.masonryListComponent.start(items).then(() => {
23+
console.log('refresh completed')
24+
})
25+
},
26+
27+
_doAppendMasonry(items) {
28+
this.masonryListComponent = this.selectComponent('#masonry')
29+
// 获取接口数据后使用瀑布流组件append方法,当append完成后调用then,是否可触底价在的标志位可以在这里处理
30+
this.masonryListComponent.append(items).then(() => {
31+
console.log('refresh completed')
32+
})
33+
},
34+
35+
})

pages/index/index.json

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"backgroundTextStyle": "light",
3+
"navigationBarBackgroundColor": "#fff",
4+
"navigationBarTitleText": "瀑布流",
5+
"navigationBarTextStyle": "black",
6+
"enablePullDownRefresh": false,
7+
"usingComponents": {
8+
"masonry": "../../components/masonry/masonry",
9+
"img-box": "../../components/img-box/img-box"
10+
}
11+
}

pages/index/index.wxml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<!--index.wxml-->
2+
<view class="container">
3+
<masonry generic:masonry-item="img-box" id="masonry" interval-width="20rpx"></masonry>
4+
</view>

pages/index/index.wxss

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**index.wxss**/
2+
.userinfo {
3+
display: flex;
4+
flex-direction: column;
5+
align-items: center;
6+
}
7+
8+
.userinfo-avatar {
9+
width: 128rpx;
10+
height: 128rpx;
11+
margin: 20rpx;
12+
border-radius: 50%;
13+
}
14+
15+
.userinfo-nickname {
16+
color: #aaa;
17+
}
18+
19+
.usermotto {
20+
margin-top: 200px;
21+
}

0 commit comments

Comments
 (0)