扩展运算符的巧妙应用
这个template模板,绑定的数据带item前缀
那么使用模板的时候,也必须保证是item
data帮绑定数据用双花括号包住item
还有wx:for-item默认也是item,因此可省略
这样带有item不利于代码复用,解决方法:
将template模板中的item前缀都去掉
然后使用模板时,在数据绑定前加...(ES6语法)
这样的好处是:
可以改变wx:for-item的属性值和data属性值(这两个必须保持一致),但不需要再去修改模板中的数据前缀
依然能够正常显示
组件的自定义属性及获取属性
创建新闻详情页
给新闻绑定点击事件,注意template和block是不能绑定事件的,所以我在template外面包裹了一个view,然后在view上绑定事件
在函数里定义好跳转到新闻详情页
查看数据可以看到,每篇新闻都有对应的postId
给每篇新闻自定义属性,传递postId
小程序中,自定义属性必须以data-开头,否则是无效的
可以看到已经传递成功
在js中使用小程序的事件对象获取到元素的属性
posts.js
在currentTarget--dataset中,存放了自定义属性
补充一个知识点
如果你设置的自定义属性名是用连字符拼接
可以看到实际结构是全部会转小写的,用连字符拼接
而在js中通过事件对象获取到属性,则会转换为驼峰形式
先静后动,先样式再数据
为了方便查看实时效果,首先将新闻详情页设置为默认页面
这样每次刷新都是这个页面
现在来编写新闻详情页 post-detail.wxml
<view class="container"> <image src="/images/post/crab.png" class="head-image"></image> <view class="author-date"> <image src="/images/avatar/3.png" class="avatar"></image> <text class="author">cyy</text> <text class="const-date">发表于</text> <text class="date">3天前</text> </view> <text class="title">正是虾肥蟹壮时</text> <view class="tool"> <view class="circle-img"> <image src="/images/icon/collection.png"></image> <image src="/images/icon/share.png" class="share-img"></image> </view> <view class="horizon"></view> </view> <text class="detail"> 菊黄蟹正肥,品尝秋之味。徐志摩把“看初花的荻芦”和“到楼外楼吃蟹”并列为秋天来杭州不能错过的风雅之事;用林妹妹的话讲是“螯封嫩玉双双满,壳凸红脂块块香”;在《世说新语》里,晋毕卓更是感叹“右手持酒杯,左手持蟹螯,拍浮酒船中,便足了一生矣。”漫漫人生长路,美食与爱岂可辜负?于是作为一个吃货,突然也很想回味一下属于我的味蕾记忆。记忆中的秋蟹,是家人的味道,弥漫着浓浓的亲情。 是谁来自山川湖海,却囿于昼夜,厨房与爱? 是母亲,深思熟虑,聪明耐心。吃蟹前,总会拿出几件工具,煞有介事而乐此不疲。告诉我们螃蟹至寒,需要佐以姜茶以祛寒,在配备的米醋小碟里,亦添入姜丝与紫苏,前者驱寒后者增香。泡好菊花茶,岁月静好,我们静等。 </text> </view>
post-detail.wxss
/* pages/posts/post-detail/post-detail.wxss */ .container{ display: flex; flex-direction:column; } .head-image{ width:100%; height:460rpx; } .author-date{ display: flex; margin:20rpx 20rpx 0 30rpx; align-items:center; } .avatar{ width:64rpx; height:64rpx; } .author{ font-size:30rpx; font-weight:300; margin-left:20rpx; color:#666; } .const-date{ font-size:24rpx; color:#999; margin-left:20rpx; } .date{ font-size:24rpx; margin-left:30rpx; } .title{ margin-left:40rpx; font-size:36rpx; font-weight:700; margin-top:30rpx; letter-spacing: 2rpx; color:#4b556c; } .tool{ margin-top:20rpx; } .circle-img{ display: flex; justify-content: flex-end; margin-right:40rpx; } .circle-img image{ width:90rpx; height:90rpx; } .horizon{ width:660rpx; height:1rpx; background-color: #e5e5e5; position: relative; bottom:45rpx; z-index:-99; margin:0 auto;/* 让线水平居中 */ } .share-img{ margin-left:30rpx; } .detail{ color:#666; margin:20rpx 30rpx; line-height: 44rpx; letter-spacing: 2rpx; }
公共样式可以写在app.wxss里
text{ font-family: MicroSoft Yahei; font-size: 24rpx; color: #666; } input{ font-family: MicroSoft YaHei; }
设置顶部文字
使用数据填充新闻详情页面
在posts.js中已经获取到了postId,传递少量数据可以在url后面直接加参数
多个参数之间使用&符号分割
在post-detail.js的onload函数中,可以用options接收到传递过来的参数
使用require引入数据文件
在onload函数中使用id获取到需要的数据,发送到data中
注意,所有setData的数据,可以在控制台的AppData中查看数据结构
将post-detail.wxml中的静态数据改为动态数据
效果图
Storage缓存的基本用法
收藏功能,需要用服务器来记录(现在可以用缓存来暂时代替)
在控制台-storage可以查看缓存
绑定事件(作用演示,非实际功能)
常见缓存操作(小程序缓存大小不能超过10M)
更多用法还是翻文档
带sync的是同步,不带sync的是异步,一般来说,异步不容易阻塞,同步更简单些
使用缓存实现文字收藏的功能
post-details.js
onload函数中实现的效果是:
读取缓存,如果存在缓存则发送到data中;如果不存在则设置为false,并更新缓存
onLoad: function (options) { var postId=options.id; this.data.postId = postId;//把postId发送到data中,方便其他函数中调用(由于不需要进行数据绑定,因此没必要使用setData) var pdata = postData.postList[postId];//postId与数据索引刚好相同,获取单篇文章的数据 this.setData({...pdata});//发送数据到data中 var postcollected = wx.getStorageSync("postcollected");//读取缓存 //如果存在缓存则发送到data if (postcollected){ var collected = postcollected[postId];//存在单篇文章缓存 if (collected){ this.setData({collected}); } }else{ postcollected={}; postcollected[postId]=false; //设置缓存 wx.setStorageSync("postcollected", postcollected); } },
//点击收藏按钮 onCollectionTap: function () { //读取缓存 var postcollected = wx.getStorageSync("postcollected"); var collected = postcollected[this.data.postId]; collected = !collected; postcollected[this.data.postId] = collected;//更新缓存 wx.setStorageSync("postcollected", postcollected); this.setData({ collected });//发送数据到data },
这样的话,data中是肯定有collected属性的,值是true或者false
在页面中用wx:if和wx:else来实现
交互反馈wx.showToast
收藏与否的文字提醒
效果图
交互反馈wx.showModal
使用wx.showModal改写刚才的wx.showToast(功能一样,实现效果不一样)
//点击收藏按钮 onCollectionTap: function () { //读取缓存 var postcollected = wx.getStorageSync("postcollected"); var collected = postcollected[this.data.postId]; wx.showModal({ title: collected ? '取消收藏' : "收藏", content: '确定执行该操作吗?', success:(res) =>{//箭头函数可以保留之前的this指向 if (res.confirm) {//点击确定 collected = !collected; postcollected[this.data.postId] = collected;//更新缓存 wx.setStorageSync("postcollected", postcollected); this.setData({ collected });//发送数据到data } else if (res.cancel) {//点击取消 console.log('取消操作') } } }); },
上面是用的ES6的箭头函数,保留了this指向,也可以使用变量保存之前的this指向
//点击收藏按钮 onCollectionTap: function () { //读取缓存 var postcollected = wx.getStorageSync("postcollected"); var collected = postcollected[this.data.postId]; var self=this;//保留this指向 wx.showModal({ title: collected ? '取消收藏' : "收藏", content: '确定执行该操作吗?', success(res){ if (res.confirm) {//点击确定 collected = !collected; postcollected[self.data.postId] = collected;//更新缓存 wx.setStorageSync("postcollected", postcollected); self.setData({ collected });//发送数据到data } else if (res.cancel) {//点击取消 console.log('取消操作') } } }); },
效果图
加入tabbar选项卡
使用tabbar最起码需要两个页面,因此我们再创建demo页面方便演示
查看文档
在app.json中添加:
效果图
如果这些组件无法满足需求,小程序有很多自定义组件,可以使用别人写好的组件
此时选择普通编辑,回到welcome页面,你会发现点击按钮无法跳转页面,这是因为受到tabBar的影响
小程序规定,如果要跳转到一个带有tabBar的页面,必须使用wx.switchTab
一些好用的小程序框架
推荐lin ui http://doc.mini.7yue.pro/
喜欢用vue编写小程序的,推荐 mpvue
喜欢用react编写小程序的,推荐 taro