欢迎光临,了解微信小程序开发,就上易用通!

【超详细】从2到3:初学者入门Demo内容详情页

发布:2018-01-25 17:21浏览: 来源:网络 作者:tianshu

如果你还想要 从0到1 和 从1到2 的细致的话,那么对不起,本文没有。
展示效果
回顾一下从1到2中最后的小作业,请确保你已经完成了如展示效果中的 列表页面,这里有 6 个数据内容哦,而且 将post-item抽取成了 template。
【超详细】从2到3:初学者入门Demo内容详情页(图1)
展示页
【超详细】从2到3:初学者入门Demo内容详情页(图2)
准备
为了更好更流畅的学习这部分内容,请确保已经阅读过先导篇: 从0 到1:初学者入门Demo、从1到2:初学者入门Demo内容列表页面。本文将一改 从0 到1 中风格,不再细枝末节的阐述,只写重要内容。
PS: 背景音乐基础内容知识,请大家 阅读 社区极速文档的 音乐播放控制API章节内容。这部分有一个完整利用 8 个API 设计的完整Demo,音乐控制,相当优雅精美哦!看一下效果的展示吧(注意:gif 展示效果,没有声音,其实快进和快退是有效果的呢!)

【超详细】从2到3:初学者入门Demo内容详情页(图3)
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 代码
  1. <view class="post-container">
  2.   <image class="post-img" src="{{isPlaying?postData.music.coverImg:postData.headImgSrc}}"></image>
  3.   <image catchtap="onMusicTap" class="audio" src="/imgs/music/music-{{isPlaying?'stop':'start'}}.png"></image>
  4.   <view class="post-author-date">
  5.     <image class="post-avatar" src="{{postData.avatar}}"></image>
  6.     <text class="post-author">{{postData.author}}</text>
  7.     <text class="const-text">发表于</text>
  8.     <text class="post-date">{{postData.dateTime}}</text>
  9.   </view>
  10.   <text class="post-title">{{postData.title}}</text>
  11.   <view class="post-collection-share">
  12.     <!-- 使用条件渲染实现一个图标的选择:会存在一个局部渲染的过程 -->
  13.     <image catchtap="onShareTap" class="post-share" src="/imgs/icon/share.png"></image>
  14.     <image catchtap="onCollectionTap" class="post-collection" src="/imgs/icon/collection{{collected?'':'-anti'}}.png"></image>
  15.   </view>
  16.   <view class="horizon"></view>
  17.   <text class="post-content">{{postData.detail}}</text>
  18. </view>
post-detail.wxss 代码
  1. .post-container {
  2.   display: flex;
  3.   flex-direction: column;
  4. }
  5. .post-img {
  6.   width: 100%;
  7.   height: 450rpx;
  8. }
  9. .audio {
  10.     width: 110rpx;
  11.     height: 102rpx;
  12.     position: absolute;
  13.     top: 180rpx;
  14.     left: 50%;
  15.     margin-left: -51rpx;
  16.     opacity: 0.6;
  17. }
  18. .post-author-date {
  19.   display: flex;
  20.   flex-direction: row;
  21.   align-items: center;
  22.   margin: 20rpx 0 0 30rpx;
  23. }
  24. .post-avatar {
  25.   width: 64rpx;
  26.   height: 64rpx;
  27. }
  28. .post-author {
  29.   font-size: 26rpx;
  30.   font-weight: 300;
  31.   margin-left: 20rpx;
  32.   color: #666;
  33. }
  34. .const-text {
  35.   font-size: 24rpx;
  36.   color: #999;
  37.   margin-left: 20rpx;
  38. }
  39. .post-date {
  40.   font-size: 24rpx;
  41.   margin-left: 30rpx;
  42.   color: #999;
  43. }
  44. .post-title {
  45.   margin-left: 40rpx;
  46.   font-size: 42rpx;
  47.   font-weight: 700;
  48.   margin-top: 30rpx;
  49.   margin-bottom: 20rpx;
  50.   letter-spacing: 2px;
  51.   color: #4b556c;
  52. }
  53. .post-collection-share {
  54.   display: flex;
  55.   flex-direction: row-reverse;
  56.   margin-right: 30rpx;
  57.   margin-bottom: 20rpx;
  58. }
  59. .post-collection-share image{
  60.   width: 80rpx;
  61.   height: 80rpx;
  62.   margin-left: 30rpx;
  63. }
  64. .horizon {
  65.   position: relative;
  66.   width: 90%;
  67.   height: 2rpx;
  68.   background-color: #e5e5e5;
  69.   margin: 0 auto;
  70.   top: -60rpx;
  71.   z-index: -99;
  72. }
  73. .post-content {
  74.   color: #666;
  75.   margin: 20rpx 30rpx 0;
  76.   line-height: 44rpx;
  77.   letter-spacing: 2px;
  78.   font-size: 30rpx;
  79. }
post-detail.js 代码
  1. var app = getApp();
  2. Page({
  3.   data: {
  4.     // 从列表项跳转时携带的的 postId ,记录一下,待用
  5.     currentPostId: "",
  6.     // 通过 postId 获取的详情内容
  7.     postData: {},
  8.     // 监控音乐播放状态,选择适合的图片
  9.     isPlaying: false,
  10.     // 当前内容是否收藏
  11.     collected: false
  12.   },
  13.   // 背景音乐的URL
  14.   currentMusicUrl: "",
  15.   // 用于记录各个收藏状态的数组,存放的是页面的postId。比如:["3","0"]
  16.   postsCollected: [],
  17.   onLoad: function (options) {
  18.     let postId = options.postId;
  19.     var that = this;
  20.     // 通过 postId 获取请内容
  21.     this.getHttpData(postId, "postData", function (data) {
  22.       that.setData({ postData: data });
  23.       that.setData({ currentPostId: postId });
  24.       that.currentMusicUrl = data.music.url;
  25.     });
  26.     // 获取文章收藏数组,更新收藏状态
  27.     this.getHttpData("postsCollected", "json", function (data) {
  28.       that.postsCollected = data;
  29.       console.log(data)
  30.       that.setData({ collected: that.postsCollected.indexOf(String(postId)) >= 0 });
  31.     });
  32.     // 若是有背景音乐正在播放的话话,判断是否是当前页面的背景音乐,以免在不同详情页的播放状态相互影响
  33.     if (app.globalData.g_currentPostId == postId) {
  34.       this.setData({ isPlaying: app.globalData.g_isPlaying });
  35.     }
  36.     // 初始化时,注册监听音乐播放状态事件
  37.     this.onAudioState();
  38.   },
  39.   // 收藏
  40.   onCollectionTap: function () {
  41.     let collected = !this.data.collected;
  42.     this.setData({ collected: collected });
  43.     wx.showToast({ title: collected ? '收藏成功' : '取消收藏', duration: 1000 });
  44.   },
  45.   // 页面卸载时,收藏状态的保存
  46.   onUnload: function () {
  47.     let postId = this.data.currentPostId;
  48.     // 当且仅当以下两种情况下才执行收藏状态的更新操作
  49.     // 如果当前页的的 postId 不在记录收藏状态数组中,且当前内容已经被收藏
  50.     // 如果当前页的的 postId 在记录收藏状态数组中,且当前内容已经取消收藏
  51.     if (this.data.collected === (this.postsCollected.indexOf(String(postId)) < 0)) {
  52.       if (this.data.collected) {
  53.         this.postsCollected.push(postId);
  54.       } else {
  55.         this.postsCollected.pop(postId);
  56.       }
  57.       this.postHttpData("postsCollected", this.postsCollected, "json");
  58.     }
  59.   },
  60.   // 点击播放背景音乐
  61.   onMusicTap: function () {
  62.     // 社区极速文档的的 音乐播放控制API篇中,有具体基础内容
  63.     let isPlaying = this.data.isPlaying;
  64.     let music = this.data.postData.music;
  65.     if (isPlaying) {
  66.       // 如果是正在播放,再次点击的话,暂停播放
  67.       wx.pauseBackgroundAudio();
  68.     } else {
  69.       // 如果是正在暂停,再次点击的话,开始播放
  70.       wx.playBackgroundAudio({
  71.         dataUrl: music.url,
  72.         title: music.title,
  73.         coverImgUrl: music.coverImg
  74.       });
  75.       // 同时将当前正在播放背景音乐的详情页的的 postId 保存到全局变量中(当拥有多个列表页和详情页时间,这是需要的)
  76.       app.globalData.g_currentPostId = this.data.currentPostId;
  77.     }
  78.     // 点击之后,播放状态取反(PS:这里和社区极速文档的的音乐播放控制API篇,使用的方式不同,为了介绍多种解决方案,费尽心机呀!)
  79.     app.globalData.g_isPlaying = !isPlaying;
  80.     this.setData({ isPlaying: !isPlaying });
  81.   },
  82.   // 监听播放状态的事件((PS:这里和社区极速文档的的音乐播放控制API篇,使用的方式不同,为了介绍多种解决方案,费尽心机呀!))
  83.   onAudioState: function () {
  84.     wx.getBackgroundAudioPlayerState({
  85.       success: (res) => {
  86.         if (res.status !== 2 && this.currentMusicUrl !== res.dataUrl) {
  87.           wx.stopBackgroundAudio();
  88.         }
  89.       }
  90.     })
  91.     wx.onBackgroundAudioPlay(() => {
  92.       app.globalData.g_isPlaying = true;
  93.       if (app.globalData.g_currentPostId == this.data.currentPostId) {
  94.         this.setData({ isPlaying: true });
  95.       }
  96.       console.log('paly');
  97.     });
  98.     wx.onBackgroundAudioPause(() => {
  99.       app.globalData.g_isPlaying = false;
  100.       this.setData({ isPlaying: false });
  101.       console.log('pause');
  102.     });
  103.     wx.onBackgroundAudioStop(() => {
  104.       app.globalData.g_isPlaying = false;
  105.       app.globalData.g_currentPostId = -1;
  106.       this.setData({ isPlaying: false });
  107.       console.log('stop');
  108.     });
  109.   },
  110.   // 从 wxappclub 的 api 中心获取数据的方法
  111.   // key 表示数据名称,_type 数据类型,callback 表示请求成功的回调函数
  112.   getHttpData: function (key, _type, callback) {
  113.     wx.request({
  114.       url: 'https://api.wxappclub.com/get',
  115.       data: {
  116.         // 笔者的API中心,提供给各位使用
  117.         "appkey": "eaa7gcwem04j8sak7hm8g88mkftgb26h",
  118.         "key": key,
  119.         "type": _type
  120.       },
  121.       method: 'GET',
  122.       header: {
  123.         'content-type': 'json'
  124.       },
  125.       success: function (res) {
  126.         if (res.data.success) {
  127.           // console.log(res.data.result.value);
  128.           callback(res.data.result.value);
  129.         }
  130.       }
  131.     });
  132.   },
  133.   // 用于提交数据的方法(爱我的话,请不要随意提交数据。谢谢!!!)
  134.   postHttpData: function (key, value, _type) {
  135.     wx.request({
  136.       url: 'https://api.wxappclub.com/put',
  137.       data: {
  138.         "appkey": "eaa7gcwem04j8sak7hm8g88mkftgb26h",
  139.         "key": key,
  140.         "value": value,
  141.         "type": _type
  142.       },
  143.       method: 'GET',
  144.       header: {
  145.         'content-type': 'json'
  146.       }
  147.     });
  148.   }
  149. })
app.js 代码(使用到了两个全局变量)
  1. App({
  2.     globalData:{
  3.         // 将音乐播放的状态保存到全局变量中,主要解决从详情页面A到达列表页在
  4.         // 到达详情页面B时,播放状态isPlaying紊乱的问题
  5.         g_isPlaying: false,
  6.         // 记录当前 g_isPlaying 是那个页面的播放状态值,与 g_isPlaying 
  7.         // 共同作用。保证不同详情页的播放状态正确
  8.         g_currentPostId: -1
  9.     }
  10. })





免责声明:本站所有文章和图片均来自用户分享和网络收集,文章和图片版权归原作者及原出处所有,仅供学习与参考,请勿用于商业用途,如果损害了您的权利,请联系网站客服处理。