【前端骚操作】小程序《动漫二次元图片分享保存工具》首页
动漫二次元图片分享保存工具
这是基于之前发布 Google Play 的 iPixel Wallpaper APP 修改而来,本就不是为了运营,只是录做视频与文章使用,有兴趣的可以看看,当前还有 Web 版本的,目前都在同步更新中。
本文先写写首页的内容吧,其他页面后续更新。
- 标签列表
- 图片列表
最近滚回原生党,除非巨型项目,否则都会使用原生,包括但不限于小程序。
标签列表
效果:
相关代码:
html
<view id="nav">
<button class="item"
bindtap='tapButton'
wx:for="{{classes}}" wx:key="{{index}}"
data-index="{{index}}">
{{item}}
</button>
</view>
这里应该使用 scroll-view,然后设置 x 方向滚动。因为当时写顺手了,就弄了个 view,然后手动 css 设置 x 滚动,据说性能是差一点,但是既然代码这样,就先这样放出来,当个反面教材。
然后,wx:for 与 wx:key 是一对冤家,基本都是一起出现,for 是循环好理解,key 是避免 for 生成的节点不唯一导致的一些 bug,这里不细说,简单记下就是一起出现即可。对了,key 要唯一,所以一般来说,index 是最好的小伙伴。
bindtap 就是 click 事件的“别名”了,但道理上是不一样的,这样记问题不大。
data-index 就是绑定的数据,可以在 js 里面类似 DOM data 属性一样获取到。
“{{x}}” 就是获取 js 里面声明的 data 绑定数据了,这个 data 数据是可以自动绑定的。
其他就是跟 HTML 区别不大了,除了标签名之外。
css
#nav {
white-space: nowrap;
overflow-x: scroll;
height: 64rpx;
}
#nav .item {
display: inline;
min-width: 120rpx;
line-height: 64rpx;
margin: 8rpx 0;
color: grey;
}
css 没什么说得,不说样式丑就行。
js
//index.js
//获取应用实例
const app = getApp()
const AV = app.globalData.AV
Page({
data: {
classes: ['Asuna'],
images: [],
},
// 获取标签列表
getClasses() {
new AV.Query('CLASSES')
.find()
.then(res => {
const classes = Array.from(res, item => item.get('className'))
this.setData({
classes: classes
})
})
.catch(console.error)
},
// 点击标签
tapButton(e) {
const className = this.data.classes[e.target.dataset.index]
this.getImages(className)
},
onReady() {
this.getClasses()
},
})
前两行是获取小程序实例,以及第三方相关,这里第三方就是之前项目提供数据源的地方,不打广告,理解成后台获取资源就行,具体获取方式在 js 里面,也不要深究。
onReady 是当前页加载前,此时获取数据,因为是异步,所以应该不会出现渲染失败。注意是应该,个人建议还是放在 onLoad 里面, 我这里因为是第三方官网的 Demo 拷贝,就没有去改它,等下有自己写的,我都是放在 onLoad。
this.setData({
classes: classes
})
React 小伙伴应该比较熟悉,这里就是小程序数据绑定修改方式,这种方式修改可以使得 wxml(HTML)里面“{{}}”绑定的视图同步更新。
没错,this.data.x = y
可以修改但是不能同步更新,明白了?
注意:与 React 不同,这玩意是同步的,不是 React 那种异步,所以不存在回调处理。
tapButton 就是绑定在标签上的点击事件,与获取图片列表有关。
那么,到这里,整个标签列表就完成了。
图片列表
效果:
相关代码:
html
<scroll-view id='main' scroll-y>
<view class='img-container'
wx:for="{{images}}"
wx:key="index"
wx:for-item="url"
data-index="{{index}}"
bindtap='tapImage'>
<image src="{{url}}" lazy-load mode="aspectFit"></image>
</view>
</scroll-view>
wx:for-item 指定循环遍历使用的 item 名,配套的有 wx:for-index 指定循环遍历使用的 index 名。是的,默认不写就是 item、index。这里为了语义清楚点,就设置成 url 了。
lazy-load 说是可以懒加载,不知道是不是我图量少,目前没有体验出来。还是说我用错了?
至于 mode="aspectFit
就是个人喜欢小程序的一点了,图片缩放处理已经被框架处理好,不要自己再去配置 width、height、自动缩放等等了。具体可以看官方说明:小程序组件——image
scroll-view 就不用说了,也是框架提供好的滚动视图,设置下具体宽高,在配置想方向就可以了:scroll-y
或 scroll-x
。
css
#main {
height: calc(100% - 64rpx);
}
.img-container {
display: inline-block;
width: 47%;
height: 400rpx;
}
.img-container:nth-child(2n + 1) {
margin-left: 2%;
margin-right: 1%;
}
.img-container:nth-child(2n) {
margin-left: 1%;
margin-right: 2%
}
image {
width: 100%;
height: 100%;
}
由于我们是竖直方向滚动,所以设置的 #main
的高。原来是想像 APP 一样实现瀑布流,但是发现 Grid 小程序好像不支持?就只能退而求其次的选择比较 low 的常规两列布局了。具体 Grid 的瀑布流,效果如下:
小程序的,哎……
中间 img-container,一样是夹层,方便以后拓展。
js
//index.js
//获取应用实例
const app = getApp()
const AV = app.globalData.AV
Page({
data: {
classes: ['Asuna'],
images: [],
},
// 获取标签下图片列表
getImages(className) {
this.setData({
images: [],
title: className
})
wx.showLoading({
title: "获取列表数据中……"
})
new AV.Query(className)
.find()
.then(res => {
wx.hideLoading()
this.setData({
images: Array.from(res, item => item.get('url'))
})
})
.catch(console.error)
},
onLoad() {
this.getImages(this.data.classes[0])
},
})
注意,默认 data 里面有一个标签,就是为了防止第一次进来没东西。
这个就相对简单不说那么具体,提一下需要注意的优化点:
- 点击标签切换的时候,要先清空图片数组,否则会出现延时或者干脆显示不匹配的问题。
- 既然是异步交互,那还是带上菊花转吧
wx.showLoading
,成功后记得关掉wx.hideLoading
。
小结
- this.setData 是驱动数据与视图更新的要点。
- 记得修改数组前清空下数组。
- 用户交互的菊花转是个好东西。
- 小程序,简单的一塌糊涂。
欢迎关注,如有需要 Web,App,小程序,请留言联系。
共同学习,写下你的评论
评论加载中...
作者其他优质文章