如果你还想要 从0到1 和 从1到2 的细致的话,那么对不起,本文没有。
展示效果
回顾一下从1到2中最后的小作业,请确保你已经完成了如展示效果中的 列表页面,这里有 6 个数据内容哦,而且 将post-item抽取成了 template。
展示页
准备
为了更好更流畅的学习这部分内容,请确保已经阅读过先导篇: 从0 到1:初学者入门Demo、从1到2:初学者入门Demo内容列表页面。本文将一改 从0 到1 中风格,不再细枝末节的阐述,只写重要内容。
PS: 背景音乐基础内容知识,请大家 阅读 社区极速文档的 音乐播放控制API章节内容。这部分有一个完整利用 8 个API 设计的完整Demo,音乐控制,相当优雅精美哦!看一下效果的展示吧(注意:gif 展示效果,没有声音,其实快进和快退是有效果的呢!)
PPPPS:该文是由从1到2而来的内容详情页,直接阅读可能带来身体的不适,足够强大的人,随意哈!
内容详情页
在 从1 到2 中,我们快速构建了一个内容详情页pages/index/post-detail/post-detail,当点击文与字简介内容的主体部分或是轮播图子项时,onPostTap 事件会携带一个 postId 参数到详情页。postId 是联接文与字简介内容和构建其对应详情页的唯一纽带。
本文没废话,直接上代码,具体的实现,大家自己来吧,如果你学习了从0到1、从1到2以及音乐播放控制API的内容,这简直不能再容易了。难道不是吗?(如果你有足够的时间,请将getHttpData、postHttpData抽取到 util.js 中吧,就像官方给的 quickstart项目那样)
请记得两句话:先骨架(wxml),再穿衣服(wxss),最后搞个小动作(js);布局时,先整体,再局部。
post-detail.wxml 代码
-
<view class="post-container">
-
<image class="post-img" src="{{isPlaying?postData.music.coverImg:postData.headImgSrc}}"></image>
-
<image catchtap="onMusicTap" class="audio" src="/imgs/music/music-{{isPlaying?'stop':'start'}}.png"></image>
-
<view class="post-author-date">
-
<image class="post-avatar" src="{{postData.avatar}}"></image>
-
<text class="post-author">{{postData.author}}</text>
-
<text class="const-text">发表于</text>
-
<text class="post-date">{{postData.dateTime}}</text>
-
</view>
-
<text class="post-title">{{postData.title}}</text>
-
<view class="post-collection-share">
-
<!-- 使用条件渲染实现一个图标的选择:会存在一个局部渲染的过程 -->
-
<image catchtap="onShareTap" class="post-share" src="/imgs/icon/share.png"></image>
-
<image catchtap="onCollectionTap" class="post-collection" src="/imgs/icon/collection{{collected?'':'-anti'}}.png"></image>
-
</view>
-
<view class="horizon"></view>
-
<text class="post-content">{{postData.detail}}</text>
-
</view>
post-detail.wxss 代码
-
.post-container {
-
display: flex;
-
flex-direction: column;
-
}
-
.post-img {
-
width: 100%;
-
height: 450rpx;
-
}
-
.audio {
-
width: 110rpx;
-
height: 102rpx;
-
position: absolute;
-
top: 180rpx;
-
left: 50%;
-
margin-left: -51rpx;
-
opacity: 0.6;
-
}
-
.post-author-date {
-
display: flex;
-
flex-direction: row;
-
align-items: center;
-
margin: 20rpx 0 0 30rpx;
-
}
-
.post-avatar {
-
width: 64rpx;
-
height: 64rpx;
-
}
-
.post-author {
-
font-size: 26rpx;
-
font-weight: 300;
-
margin-left: 20rpx;
-
color: #666;
-
}
-
.const-text {
-
font-size: 24rpx;
-
color: #999;
-
margin-left: 20rpx;
-
}
-
.post-date {
-
font-size: 24rpx;
-
margin-left: 30rpx;
-
color: #999;
-
}
-
.post-title {
-
margin-left: 40rpx;
-
font-size: 42rpx;
-
font-weight: 700;
-
margin-top: 30rpx;
-
margin-bottom: 20rpx;
-
letter-spacing: 2px;
-
color: #4b556c;
-
}
-
.post-collection-share {
-
display: flex;
-
flex-direction: row-reverse;
-
margin-right: 30rpx;
-
margin-bottom: 20rpx;
-
}
-
.post-collection-share image{
-
width: 80rpx;
-
height: 80rpx;
-
margin-left: 30rpx;
-
}
-
.horizon {
-
position: relative;
-
width: 90%;
-
height: 2rpx;
-
background-color: #e5e5e5;
-
margin: 0 auto;
-
top: -60rpx;
-
z-index: -99;
-
}
-
.post-content {
-
color: #666;
-
margin: 20rpx 30rpx 0;
-
line-height: 44rpx;
-
letter-spacing: 2px;
-
font-size: 30rpx;
-
}
post-detail.js 代码
-
var app = getApp();
-
Page({
-
data: {
-
// 从列表项跳转时携带的的 postId ,记录一下,待用
-
currentPostId: "",
-
// 通过 postId 获取的详情内容
-
postData: {},
-
// 监控音乐播放状态,选择适合的图片
-
isPlaying: false,
-
// 当前内容是否收藏
-
collected: false
-
},
-
// 背景音乐的URL
-
currentMusicUrl: "",
-
// 用于记录各个收藏状态的数组,存放的是页面的postId。比如:["3","0"]
-
postsCollected: [],
-
onLoad: function (options) {
-
let postId = options.postId;
-
var that = this;
-
// 通过 postId 获取请内容
-
this.getHttpData(postId, "postData", function (data) {
-
that.setData({ postData: data });
-
that.setData({ currentPostId: postId });
-
that.currentMusicUrl = data.music.url;
-
});
-
// 获取文章收藏数组,更新收藏状态
-
this.getHttpData("postsCollected", "json", function (data) {
-
that.postsCollected = data;
-
console.log(data)
-
that.setData({ collected: that.postsCollected.indexOf(String(postId)) >= 0 });
-
});
-
// 若是有背景音乐正在播放的话话,判断是否是当前页面的背景音乐,以免在不同详情页的播放状态相互影响
-
if (app.globalData.g_currentPostId == postId) {
-
this.setData({ isPlaying: app.globalData.g_isPlaying });
-
}
-
// 初始化时,注册监听音乐播放状态事件
-
this.onAudioState();
-
},
-
// 收藏
-
onCollectionTap: function () {
-
let collected = !this.data.collected;
-
this.setData({ collected: collected });
-
wx.showToast({ title: collected ? '收藏成功' : '取消收藏', duration: 1000 });
-
},
-
// 页面卸载时,收藏状态的保存
-
onUnload: function () {
-
let postId = this.data.currentPostId;
-
// 当且仅当以下两种情况下才执行收藏状态的更新操作
-
// 如果当前页的的 postId 不在记录收藏状态数组中,且当前内容已经被收藏
-
// 如果当前页的的 postId 在记录收藏状态数组中,且当前内容已经取消收藏
-
if (this.data.collected === (this.postsCollected.indexOf(String(postId)) < 0)) {
-
if (this.data.collected) {
-
this.postsCollected.push(postId);
-
} else {
-
this.postsCollected.pop(postId);
-
}
-
this.postHttpData("postsCollected", this.postsCollected, "json");
-
}
-
},
-
// 点击播放背景音乐
-
onMusicTap: function () {
-
// 社区极速文档的的 音乐播放控制API篇中,有具体基础内容
-
let isPlaying = this.data.isPlaying;
-
let music = this.data.postData.music;
-
if (isPlaying) {
-
// 如果是正在播放,再次点击的话,暂停播放
-
wx.pauseBackgroundAudio();
-
} else {
-
// 如果是正在暂停,再次点击的话,开始播放
-
wx.playBackgroundAudio({
-
dataUrl: music.url,
-
title: music.title,
-
coverImgUrl: music.coverImg
-
});
-
// 同时将当前正在播放背景音乐的详情页的的 postId 保存到全局变量中(当拥有多个列表页和详情页时间,这是需要的)
-
app.globalData.g_currentPostId = this.data.currentPostId;
-
}
-
// 点击之后,播放状态取反(PS:这里和社区极速文档的的音乐播放控制API篇,使用的方式不同,为了介绍多种解决方案,费尽心机呀!)
-
app.globalData.g_isPlaying = !isPlaying;
-
this.setData({ isPlaying: !isPlaying });
-
},
-
// 监听播放状态的事件((PS:这里和社区极速文档的的音乐播放控制API篇,使用的方式不同,为了介绍多种解决方案,费尽心机呀!))
-
onAudioState: function () {
-
wx.getBackgroundAudioPlayerState({
-
success: (res) => {
-
if (res.status !== 2 && this.currentMusicUrl !== res.dataUrl) {
-
wx.stopBackgroundAudio();
-
}
-
}
-
})
-
wx.onBackgroundAudioPlay(() => {
-
app.globalData.g_isPlaying = true;
-
if (app.globalData.g_currentPostId == this.data.currentPostId) {
-
this.setData({ isPlaying: true });
-
}
-
console.log('paly');
-
});
-
wx.onBackgroundAudioPause(() => {
-
app.globalData.g_isPlaying = false;
-
this.setData({ isPlaying: false });
-
console.log('pause');
-
});
-
wx.onBackgroundAudioStop(() => {
-
app.globalData.g_isPlaying = false;
-
app.globalData.g_currentPostId = -1;
-
this.setData({ isPlaying: false });
-
console.log('stop');
-
});
-
},
-
// 从 wxappclub 的 api 中心获取数据的方法
-
// key 表示数据名称,_type 数据类型,callback 表示请求成功的回调函数
-
getHttpData: function (key, _type, callback) {
-
wx.request({
-
url: 'https://api.wxappclub.com/get',
-
data: {
-
// 笔者的API中心,提供给各位使用
-
"appkey": "eaa7gcwem04j8sak7hm8g88mkftgb26h",
-
"key": key,
-
"type": _type
-
},
-
method: 'GET',
-
header: {
-
'content-type': 'json'
-
},
-
success: function (res) {
-
if (res.data.success) {
-
// console.log(res.data.result.value);
-
callback(res.data.result.value);
-
}
-
}
-
});
-
},
-
// 用于提交数据的方法(爱我的话,请不要随意提交数据。谢谢!!!)
-
postHttpData: function (key, value, _type) {
-
wx.request({
-
url: 'https://api.wxappclub.com/put',
-
data: {
-
"appkey": "eaa7gcwem04j8sak7hm8g88mkftgb26h",
-
"key": key,
-
"value": value,
-
"type": _type
-
},
-
method: 'GET',
-
header: {
-
'content-type': 'json'
-
}
-
});
-
}
-
})
app.js 代码(使用到了两个全局变量)
-
App({
-
globalData:{
-
// 将音乐播放的状态保存到全局变量中,主要解决从详情页面A到达列表页在
-
// 到达详情页面B时,播放状态isPlaying紊乱的问题
-
g_isPlaying: false,
-
// 记录当前 g_isPlaying 是那个页面的播放状态值,与 g_isPlaying
-
// 共同作用。保证不同详情页的播放状态正确
-
g_currentPostId: -1
-
}
-
})
|