效果图
实现分析
从效果图上分析,书籍详情是通过点击首页的
item
后进入。
进入详情页之后页面顶部显示书籍的相关信息,同时判断用户是否登录,未登录则弹出一个授权登录窗口。
点击登录之后即可加载出用户评论信息。
通过上图我们可以分析出静态页面的主要结构如下:
- 书籍信息
- 左侧布局是图书图片
- 中间布局从上到下是:名称、作者、出版社
- 右侧布局是收藏
icon
- 登录提示弹窗
- 上部分是提示文本
- 下部分是登录按钮
- 评论列表
- 左侧是评论人头像
- 右侧上部分是评论人名字
- 右侧中间部分是评论信息
- 右侧下部分是评论时间
- 评论按钮
- 固定在底部的一个按钮
ps:如果不想看代码可直接跳过了,下面都是具体的代码实现了
具体实现
具体实现主要从
wxml
,wxss
,js
这三个文件去介绍。
wxml
实现了页面的绘制,然后通过wxss
美化页面的样式,最后通过js
文件获取数据并将数据填充wxml
。
顶部书籍信息实现
wxml
规定了各个组件的摆放顺序。
<view class="book-container bg-white"> <view class="book-info"> // 书籍图片 <image class="book-image" mode="scaleToFill" src="{{bookInfo.bkcover}}"></image> // 书籍文字信息 <view class="book-desc"> <text class="book-main-text">{{bookInfo.bkname}}</text> <text class="book-text">{{bookInfo.bkauthor}}</text> <text class="book-text">{{bookInfo.bkpublisher}}</text> </view> </view> // 收藏 icon <view class="button-area" catchtap="onLikeClick"> <block wx:if="{{isLike}}"> <l-icon name="like" color="#FFE57F" size="50" /> </block> <block wx:else> <l-icon name="like" color="#34BFA3" size="50" /> </block> </view> </view>
wxss
样式美化了图书封面,图书名称,作者信息等内容
.book-container { /*border: 1px solid black;*/ display: flex; flex-direction: row; justify-content: space-between; align-items: center; padding: 50rpx 30rpx; } .book-info { /*border: 1px solid red;*/ display: flex; flex-direction: row; align-items: flex-start; justify-content: space-between; } .book-image { width: 200rpx; height: 300rpx; box-shadow: 0 0 10rpx #cdcdcd; } .book-desc { /*border: 1px solid yellow;*/ display: flex; flex-direction: column; justify-content: space-between; align-items: flex-start; padding-left: 30rpx; } .book-main-text { color: #1e1e1e; font-size: 35rpx; } .book-text { color: #8a8a8a; font-size: 30rpx; } .button-area { /*border: 1px solid blue;*/ display: flex; flex-direction: row; align-items: center; }
js
文件伪代码如下:获取了书籍信息、用户是否收藏图书的信息
// 获取书籍信息 _getBookInfo(bk_id) { bookModel.getBookInfo(bk_id) .then(res => { this.data.bookInfo = res this.setData({ bookInfo: this.data.bookInfo }); }) }, // 获取用户是否收藏该书籍 _getUserLikeIt(bk_id) { bookModel.getLikeStatus(bk_id) .then(res => { this.data.bookIsLike = res this.setData({ isLike: this.data.bookIsLike }); }) },
登录弹窗实现
弹窗使用了lin-ui
中的l-popup
组件,具体的组件使用可查看 官方文档。
wxml
文件实现了组件的摆放顺序。
<!-- 弹出登录弹窗 --> <l-popup show="{{unLogin}}" content-align="center" showMask="true" bind:lintap="onPopupTap" locked="{{true}}"> <view class='center'> <text>收藏功能需要</text> <text>登录之后才能使用呢~</text> <l-button bind:getuserinfo="getUserInfo" open-type="getUserInfo">允许登录</l-button> </view> </l-popup>
wxss
文件控制了弹窗居中显示,已经窗口大小、字体大小等内容。
.center { height: 250rpx; width: 500rpx; line-height: 100rpx; background: #fff; text-align: center; align-items: center; justify-content: center; align-content: center; color: #555; border-radius: 8rpx; font-size: 28rpx; }
js
文件中判断了用户是否登录,根据不同的登录状态控制弹窗是否显示
if (app.globalData.userInfo != null) { that.setData({ unLogin: false }) // 评论需要登录 this._getCommentData(that.data.bk_id) } else { that.setData({ unLogin: true }) }
评论列表实现
进入评论列表,首先会加载loading
进度条,如果没有评论列表会显示暂无评论的提示
,如果有评论数据会显示评论数据。
评论列表的wxml
如下:
<view class="comment-container"> <view class="comment-title"> <text>--------- 评论 ---------</text> </view> // 加载中进度条 <view class="comment-loading" wx:if="{{commentLoading}}"> <view class="donut"></view> </view> // 评论布局列表 <view class="comment-area" wx:else> // 有评论数据 <block wx:if="{{commentList.length > 0}}"> <view class="comment-item" wx:for="{{commentList}}" wx:key="index"> // 头像 <view class="avatar-container"> <image mode="scaleToFill" src="{{item.uavatar}}" class="user-avatar"></image> </view> // 用户名、内容、评论时间 <view class="comment-content"> <text class="user-name">{{item.uname}}</text> <text class="user-comment">{{item.ucontent}}</text> <text class="comment-time">{{item.created_at}}</text> </view> </view> </block> // 没有评论提示布局 <block wx:else> <view class="comment-placeholder">来当第一个评论的人吧~</view> </block> </view> </view>
评论列表的wxss
如下:
.comment-container { padding-top: 30rpx; } .comment-title { /*border: 1px solid black;*/ display: flex; justify-content: center; align-items: center; margin-bottom: 30rpx; } .comment-title > text { font-size: 30rpx; color: #cdcdcd; } .comment-area { /*border: 1px solid black;*/ padding: 20rpx 30rpx; } .comment-item { display: flex; flex-direction: row; justify-content: flex-start; align-items: flex-start; margin-bottom: 20rpx; } .comment-placeholder { display: flex; justify-content: center; align-items: center; color: #dcdcdc; } .comment-item:last-child { margin-bottom: 180rpx; } .avatar-container { width: 80rpx; height: 80rpx; margin-right: 20rpx; } .user-avatar { width: 80rpx; height: 80rpx; /*border: 1px solid red;*/ } .comment-content { display: flex; max-width: 590rpx; flex-direction: column; justify-content: flex-start; align-items: flex-start; } .user-name { color: #8a8a8a; font-size: 30rpx; } .user-comment { display: inline-block; margin-top: 10rpx; color: #1e1e1e; font-size: 35rpx; } .comment-time { display: inline-block; margin-top: 10rpx; color: #cdcdcd; font-size: 20rpx; } .comment-loading { display: flex; justify-content: center; align-items: center; }
评论列表的js
如下:调用接口获取数据库中的评论数据。
_getCommentData(bk_id) { let that = this bookModel.getPageData(bk_id) .then(res => { console.log(res) if (res.length > 0) { // 关闭进度条 that._commentSetTimeOut(res, false) } else if (res.error_code == 10006) { // token 不合法,需要登录 app.showInfo('token不合法,请去登录'); // 关闭进度条 that._commentSetTimeOut([], false) } else { // 关闭进度条 that._commentSetTimeOut([], false) } }) .catch(err => { console.log('错误信息:' + err); // 关闭进度条 that._commentSetTimeOut([], false) }) },
底部固定的评论按钮实现
主要就是如何使按钮底部固定,同时不会遮挡住评论列表
wxml
如下:有意思的是class
中也能直接写样式,新发现!
<view class="fixed-bottom block-full-width flex-container bg-white"> <button class="full-button" type="primary" open-type="getUserInfo" catchtap="goComment" data-id="{{bookInfo.id}}" data-name="{{bookInfo.name}}"> 写评论 </button> </view>
以上就是本次的介绍。
扫码关注公众号,轻撩即可。