本次的系列博文的知识点讲解和代码,主要是来自于 七月老师 的书籍《微信小程序开发:入门与实践》,由个人总结并编写,关于更多微信小程序开发中的各项技能,以及常见问题的解决方案,还请大家购买书籍进行学习实践,该系列博文的发布已得到七月老师的授权许可
0 系列文章目录
01 WeChat 从一个简单的“Welcome”页面来开启小程序之旅吧
02 WeChat 文章列表页面(一)
03 WeChat 文章列表页面(二)
04 WeChat 模块、模板与缓存
05 WeChat 文章详情页
06 WeChat 文章评论页(一)
07 WeChat 文章评论页(二)
08 WeChat 文章评论页(三)
09 WeChat 背景音乐播放
1 跳转文章详情页面
新建文章详情页,在 app.json
的 page
数组下新增页面路径 ``,保存之后,开发工具会自动生成 post-detail
详情页,在 post.wxml
中增加 view
容器包裹 template
模板,并注册跳转文章详情页事件,这里没有在 template
或 block
标签上注册事件,是因为它们在编译之后“消失”了
<!--pages/post/post.wxml-->
<block wx:for="{{postList}}" wx:for-index="idx" wx:for-item="item">
<view catchtap="onTapToDetail" data-post-id="{{item.postId}}">
<template is="postItemTpl" data="{{...item}}" />
</view>
</block>
我们在 post.js
文件中添加 onTapToDetail
事件,通过传入的 event 事件对象,获取到传入的 postId
,其中 currentTarget
代表事件绑定的当前组件,而 dataset
对象里包含当前组件中所有属性名以 data-
开头的自定义属性值
// pages/post/post.js
import { DBPost } from '../../db/DBPost.js'
Page({
...
onTapToDetail(event) {
const postId = event.currentTarget.dataset.postId
console.log(postId)
wx.navigateTo({
url: `post-detail/post-detail?id=${postId}`
})
}
})
在 post-detail
页面中获取 postId
// pages/post/post-detail/post-detail.js
Page({
data: {},
onLoad: function (options) {
let postId = options.id
}
})
2 跳转文章详情页面
现在我们主要的代码编辑工作集中在 post-detail
这个页面上,但每当保存刷新小程序后,项目都将从欢迎页面启动,我们不得不依次点击启动页面、文章列表,才能进入到文章详情页面以浏览文章详情的效果,这样非常不方便我们调试页面
官方提供了一个【自定义编译】功能,可用于定义小程序的启动页面,点击【普通编译】,随后在弹出的菜单中选择【添加编译模式】,将启动页面设置为 pages/post/post-detail/post-detail
,启动参数可设为 id=4
,若是有多个参数,可使用 & 进行连接
我们在文章详情页中拿到了 postId
,接下来需要根据这个 postId
去缓存数据库中读取文章详细数据,并将数据用于构建文章详情页,在 DBPost.js
文件中修改 constructor
构造函数,增加一个构造参数 postId
,并将其保存到 this
变量中,随后增加 getPostItemById
方法,用于获取指定 id
的文章数据
// db/DBPost.js
class DBPost {
constructor(postId) {
this.storageKeyName = 'postList'
this.postId = postId
}
...
// 获取指定id的文章数据
getPostItemById() {
let postsData = this.getAllPostData()
const len = postsData.length
for(let i = 0; i < len; i++) {
if(postsData[i].postId == this.postId) {
return {
// 当前文章在缓存数据库数组中的序号
index: i,
data: postsData[i]
}
}
}
}
}
随后我们在 post-detail.js
中获取指定 id
的文章数据,并使用 this.setData
绑定该数据
// pages/post/post-detail/post-detail.js
import { DBPost } from "../../../db/DBPost"
Page({
data: {},
onLoad: function (options) {
let postId = options.id
this.dbPost = new DBPost(postId)
this.postData = this.dbPost.getPostItemById().data
this.setData({
post: this.postData
})
}
})
3 编写文章详情页面
<!--pages/post/post-detail/post-detail.wxml-->
<view class="container">
<image class="head-image" src="{{post.postImg}}"/>
<text class="title">{{post.title}}</text>
<view class="author-date">
<view class="author-box">
<image class="avatar" src="{{post.avatar}}" />
<text class="author">{{post.author}}</text>
</view>
<text class="date">{{post.dateTime}}</text>
</view>
<text class="detail">{{post.detail}}</text>
</view>
/* pages/post/post-detail/post-detail.wxss */
.container {display:flex;flex-direction:column;}
.head-image {width:750rpx;height:460rpx;}
.title {font-size:20px;margin:30rpx;letter-spacing:2px;color:#4b556c;}
.author-date {display:flex;flex-direction:row;margin-top:15rpx;margin-left:30rpx;align-items:center;justify-content:space-between;font-size:13px;}
.author-box {display:flex;flex-direction:row;align-items:center;}
.avatar {height:50rpx;width:50rpx;}
.author {font-weight:300;margin-left:20rpx;color:#666;}
.date {color:#919191;margin-right:38rpx;}
.detail {color:#666;margin:40rpx 22rpx 0;line-height:44rpx;letter-spacing:1px;font-size:14px;}
保存并刷新页面后,文章详情页将正确地显示出来,如下图所示
在 post.json
文件中配置导航栏文字
{
"navigationBarTextStyle": "white",
"navigationBarTitleText": "标题"
}
在 post-detail.js
文件中动态设置导航栏文字为文章标题
Page({
...
onReady: function() {
wx.setNavigationBarTitle({
title: this.postData.title
})
}
})
4 收藏、点赞功能
由于我们的数据库只在本地,无法多次收藏同一篇文章,所以收藏数量永远只在初始数量的基础上 +1 或者 -1,分别对应点击收藏和取消收藏两种状态,但在真实的项目中,这个收藏数量却是要受到所有用户收藏、取消文章动作影响的,同样的情况也会出现在【文章点赞】功能中
接下来我们编写 3 个功能的功能按钮,每个按钮都绑定了对应的点击事件及当前文章的 id
,并通过条件渲染 wx:if
和 wx:else
来控制图片的更换
<!--pages/post/post-detail/post-detail.wxml-->
<view class="container">
...
</view>
<view class="tool">
<view class="tool-item" catchtap="onUpTap" data-post-id="{{post.postId}}">
<image animation="{{animationUp}}" wx:if="{{post.upStatus}}" src="/images/icon/wx_app_liked.png" />
<image animation="{{animationUp}}" wx:else src="/images/icon/wx_app_like.png" />
<text>{{post.upNum}}</text>
</view>
<view class="tool-item comment" catchtap="onCommentTap" data-post-id="{{post.postId}}">
<image src="/images/icon/wx_app_message.png"></image>
<text>{{post.commentNum}}</text>
</view>
<view class="tool-item" catchtap="onCollectionTap" data-post-id="{{post.postId}}">
<image wx:if="{{post.collectionStatus}}" src="/images/icon/wx_app_collected.png" />
<image wx:else src="/images/icon/wx_app_collect.png" />
<text>{{post.collectionNum}}</text>
</view>
</view>
/* pages/post/post-detail/post-detail.wxss */
.tool {height:64rpx;margin:20rpx 28rpx 20rpx 0;display:flex;justify-content:center;}
.tool-item {align-items:center;margin-right:30rpx;display:flex;}
.tool-item:last-child {margin-right:0rpx;}
.tool-item image {height:30rpx;width:30rpx;margin-right:10rpx;}
.comment image {transform:scale(.85);}
接着我们在 DBPost.js
文件中添加 updatePostData
方法,用来更新本地的点赞、评论信息、收藏和阅读量
//收藏
collect() {
return this.updatePostData("collect")
}
//点赞
up() {
let data = this.updatePostData("up")
return data
}
//更新本地的点赞、评论信息、收藏、阅读量
updatePostData(category, newComment) {
let itemData = this.getPostItemById(),
postData = itemData.data,
allPostData = this.getAllPostData()
switch (category) {
case "collect":
//处理收藏
if (!postData.collectionStatus) {
//如果当前状态是未收藏
postData.collectionNum++
postData.collectionStatus = true
} else {
// 如果当前状态是收藏
postData.collectionNum--
postData.collectionStatus = false
}
break
case "up":
if (!postData.upStatus) {
postData.upNum++
postData.upStatus = true
} else {
postData.upNum--
postData.upStatus = false
}
break
case "comment":
postData.comments.push(newComment)
postData.commentNum++
break
case "reading":
postData.readingNum++
break
default:
break
}
// 更新缓存数据库
allPostData[itemData.index] = postData
this.execSetStorageSync(allPostData)
return postData
}
接着我们编写收藏文章的 onCollectionTap
事件函数,以及点赞操作的 onUpTap
事件函数,并通过 wx.showToast
进行友好的反馈提示交互
// pages/post/post-detail/post-detail.js
onCollectionTap: function (event) {
let newData = this.dbPost.collect();
// 重新绑定数据。注意,不要将整个newData全部作为setData的参数,
// 应当有选择的更新部分数据
this.setData({
'post.collectionStatus': newData.collectionStatus,
'post.collectionNum': newData.collectionNum
})
// 交互反馈
wx.showToast({
title: newData.collectionStatus ? "收藏成功" : "取消成功",
duration: 1000,
icon: "success",
mask: true
})
},
onUpTap: function (event) {
let newData = this.dbPost.up();
this.setData({
'post.upStatus': newData.upStatus,
'post.upNum': newData.upNum
})
}
该章节的内容到这里就全部结束了,源码我已经发到了 GitHub WeChat_05 上了,有需要的同学可自行下载
End of File
行文过程中出现错误或不妥之处在所难免,希望大家能够给予指正,以免误导更多人,最后,如果你觉得我的文章写的还不错,希望能够点一下喜欢和关注,为了我能早日成为简书优秀作者献上一发助攻吧,谢谢!^ ^