一、项目介绍
该小程序能够通过底部选项卡切换文章和电影两个主页面。
文章列表页实现了轮播、页面跳转。文章详情页BackgroundAudioManager实现了背景音乐的播放和暂停,利用CSS3实现播放图标旋转动画,利用storage模拟收藏功能。
电影列表页利用条件渲染实现列表和搜索两个板块切换,实现了电影搜索功能。更多电影页面onPullDownRefresh()、onReachBottom()实现下拉刷新、触底加载。电影详情页面scroll-view实现滚动查看演员,previewImage实现放大查看图片。
充分运用template模板,全局公用方法提高了代码复用性。
二、使用知识
(一)、框架:
详见我的文章: 小程序笔记:框架
(二)、组件
1. 视图容器
view:视图容器
scroll-view:可滚动视图区域
<scroll-view class="cast-imgs" scroll-x="true" style="width:100%">
*注意:在滚动 scroll-view 时会阻止页面回弹,所以在 scroll-view 中滚动,是无法触发 onPullDownRefresh。若要使用下拉刷新,请使用页面的滚动,而不是 scroll-view ,这样也能通过点击顶部状态栏回到页面顶部
swiper:滑块视图容器
注意:其中只可放置<swiper-item/>组件,否则会导致未定义的行为。swiper-item
仅可放置在<swiper/>组件中,宽高自动设置为100%。
<swiper catchtap='onSwiperTap' autoplay='{{true}}' indicator-dots='{{true}}' circular='{{true}}'>
<swiper-item>
<image src='/images/wx.png' data-post-id='3' />
</swiper-item>
<swiper-item>
<image src='/images/vr.png' data-post-id='4' />
</swiper-item>
...
</swiper>
2. 基础组件
icon图标
<icon type='search' size='16' color='#405f80' />
text文本
<text class='user_name'>Hello,</text>
3. 表单组件
button:按钮
button class='moto' bindtap='ontap'>开启小程序之旅</button>
input:输入框
<input placeholder='你的名字' placeholder-class='placeholder' value='{{inputValue}}' bindfocus='onSearchFocus' bindconfirm='onSearchConfirm' />
4. 媒体组件
image:图片
<image class='head-img' src='{{movie.movieImg}}' mode='aspectFill' />
5. 开放能力
open-data:用于展示微信开放的数据。
<open-data class='user_avatar' type="userAvatarUrl" />
(三)、API
1.网络
发起请求
wx.request,发起 HTTPS 网络请求。
wx.request({
url: url,
header: {
"Content-Type": "json"
},
method: 'GET',
success(res) {
that.processDoubanData(res.data, settedkey, categoryTitle)
},
fail(err) {
console.log(err.errMsg);
},
})
2.媒体
背景音频
wx.getBackgroundAudioManager()
获取全局唯一的背景音频管理器。 小程序切入后台,如果音频处于播放状态,可以继续播放。但是后台状态不能通过调用API操纵音频的播放状态。
let backgroundMusic = wx.getBackgroundAudioManager();
图片
wx.previewImage(Object object)
在新页面中全屏预览图片。预览的过程中用户可以进行保存图片、发送给朋友等操作。
wx.previewImage({ urls: [url], })
3.数据缓存
wx.setStorageSync(Object object)
将数据存储在本地缓存中指定的 key 中。会覆盖掉原来该 key 对应的内容。数据存储生命周期跟小程序本身一致,即除用户主动删除或超过一定时间被自动清理,否则数据都一直可用。
wx.setStorageSync('posts_collected', postsCollected);
wx.getStorageSync(Object object)
从本地缓存中异步获取指定 key 的内容
let postsCollected = wx.getStorageSync('posts_collected');
4.界面
(1)交互
wx.showToast(Object object)
显示消息提示框
wx.showToast({ title: this.data.collected ? '已成功收藏' : '已取消收藏', })
wx.showModal(Object object)
显示模态对话框
wx.showModal({
title: itemList[res.tapIndex],
content: "确定分享吗?",
success(res) {
...
}
})
wx.showActionSheet(Object object)
显示操作菜单
wx.showActionSheet({
itemList: itemList,
itemColor: '#405f80',
success(res) {
console.log(res);
...
},
fail(res) {
console.log(res.errMsg)
}
})
(2)导航栏
wx.showNavigationBarLoading(Object object)
在当前页面显示导航条加载动画
wx.showNavigationBarLoading();
wx.hideNavigationBarLoading(Object object)
在当前页面隐藏导航条加载动画
wx.hideNavigationBarLoading();
wx.setNavigationBarTitle(Object object)
动态设置当前页面的标题
wx.setNavigationBarTitle({ title: this.data.category, })
(3)下拉刷新
######## wx.stopPullDownRefresh(Object object)
停止当前页面下拉刷新。
wx.stopPullDownRefresh();
5.路由
wx.navigateTo(Object object)
保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面。使用wx.navigateBack可以返回到原页面。
wx.navigateTo({ url: './post-detail/post-detail?id=' + postId, })
wx.redirectTo(Object object)
关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面。
wx.redirectTo({ url: 'test?id=1' })
wx.switchTab(Object object)
跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
wx.switchTab({ url: '/page/posts/post', })
wx.reLaunch(Object object)
关闭所有页面,打开到应用内的某个页面
wx.reLaunch({ url: 'test?id=1' })
三、重要方法
(一)公用方法utils.js
//评分转化为星星数组
function convertToStarsArray(stars) {
let num = stars.substring(0,1);
let newstars = [];
for (let i = 0;i < 5;i++) {
if (i<num) {
newstars.push(1);
} else {
newstars.push(0);
}
};
return newstars;
};
//发送网络请求
function http(url,callBack) {
wx.request({
url: url,
header: {
"Content-Type": "json"
},
method: 'GET',
success(res) {
callBack(res.data)
},
fail(err) {
console.log(err.errMsg);
},
})
};
(二)文章详情页movie-detail.js
//初始化收藏
initColleced: function (postId) {
let postsCollected = wx.getStorageSync('posts_collected');
let postCollected = postsCollected[postId];
if (postsCollected && postCollected) {
this.setData({
collected: postCollected,
});
}
},
//处理收藏函数
handleCollected: function (id) {
let postsCollected = wx.getStorageSync('posts_collected') ? wx.getStorageSync('posts_collected') : {};
let postCollected = !this.data.collected;
this.setData({
collected: postCollected,
});
postsCollected[id] = postCollected;
wx.setStorageSync('posts_collected', postsCollected);
},
//点击收藏按钮
onCollectionTap: function (event) {
this.handleCollected(this.data.postId);
wx.showToast({
title: this.data.collected ? '已成功收藏' : '已取消收藏',
})
},
//初始化音乐
initMusic() {
let music = this.data.postData.music;
let isPlayingMusic = true;
let backgroundMusic = wx.getBackgroundAudioManager();
backgroundMusic.src = music.url;
backgroundMusic.title = music.title;
backgroundMusic.coverImgUrl = music.coverImg;
this.setData({
isPlayingMusic: isPlayingMusic,
backgroundMusic: backgroundMusic,
});
//监听音乐播放的总控开关、结束播放
backgroundMusic.onPlay(this.musicOnPlay);
backgroundMusic.onPause(this.musicOnPause);
backgroundMusic.onEnded(this.musicOnEnded);
},
//点击音乐按钮
onMusicTap() {
let isPlayingMusic = this.data.isPlayingMusic;
if (isPlayingMusic) {
this.data.backgroundMusic.pause();
} else {
this.data.backgroundMusic.play();
};
isPlayingMusic = !this.data.isPlayingMusic;
console.log(isPlayingMusic);
this.setData({
isPlayingMusic: isPlayingMusic,
})
}
(三)movies.js
//处理豆瓣数据
processDoubanData(DoubanData, settedkey, categoryTitle) {
let movies = [];
for (let idx in DoubanData.subjects) {
let subject = DoubanData.subjects[idx];
console.log(subject);
let title = (subject.title.length <= 6) ? subject.title : subject.title.substring(0, 6) + '...';
let stars = utils.convertToStarsArray(subject.rating.stars);
let movie = {
coverImage: subject.images.large,
title: title,
score: subject.rating.average,
stars: stars,
movieId: subject.id,
}
movies.push(movie);
};
let readyData = {};
readyData[settedkey] = {
categoryTitle: categoryTitle,
movies: movies,
};
this.setData(readyData);
},
网友评论