微信小程序学习之电影&&影评小程序
博客班级 | https://edu.cnblogs.com/campus/zjcsxy/SE2020 |
作业要求 | https://edu.cnblogs.com/campus/zjcsxy/SE2020/homework/11334 |
作业目标 | 1.编写一个小程序,可以全新编写,也可以学习别人的小程序进行修改 2.熟悉git代码管理流程,将源代码上传到到 3.github在博客园班级中写一篇相应的博文 |
作业源代码 | https://github.com/Pkiller112/movie-read |
学号 | 31801135 |
院系 | 浙大城市学院计算机专业 |
·前言
第一次学做微信小程序,起初下了github上别人的程序代码啃,结果很不理想,原因一是电影小程序都调用了过期的API,小程序打不开的情况下无法进行调试,只能硬啃代码理解,但是又无法理解API调用后的JS;二是对于微信小程序,不论是在文件结构上还是代码语句上,都处于一无所知之中,遂转念,不如重新开始写一个,发现从0开始写的学习效率最好。本文主要介绍我的小程序以及碰到的困难。P.S.使用工具为微信官方的微信开发者工具
本文主要学习并理解了https://github.com/sesine/wechat-weapp-movie、https://github.com/kami-zeros/zqqWeChatDouBanMovie的代码,在此基础上进行了个人改动
·界面展示
·文件结构
popular、talking、my文件分别对应三个页面“热映”、“影评”、“我的”,moviemore和talkingmore分别为电影详细页面和影评详细页,favorite、history、photo、skin分别对应“收藏”、“浏览记录”、“相册”、“皮肤”页面。
据我个人的学习理解:
1.js后缀的文件中为页面的功能代码,像收藏啊点击效果这类功能的实现代码都在该文件中。
2.json后缀的文件代码设置的是小程序上下边框的显示,举个例子
"window": {
"navigationBarBackgroundColor": "#47a86c",
"navigationBarTextStyle": "white",
"navigationBarTitleText": "电影推荐",
"backgroundColor": "#fff",
"backgroundTextStyle": "dark",
"enablePullDownRefresh": true
},
这一段设置的就是小程序最上端的样式(P.S. app.XX文件中设置的是全局效果,如果对每个页面有细分效果要求可以在子页面的文件中设置)
3.wxml和wxss,对于学过web知识的人来说就比较好理解了,其功能类比于html和css,就是页面的布局和样式设置
·布局上的收获——wx:for="{{XX}}"
因为之前学过web,所以在html和css上有一定的基础,但还是在这里学到了新的知识。之前只会用在一个盒子中用ul li重复写很多一摸一样格式的布局,在微信小程序的制作中学到了新的打开方式
首先用一个数组将每个元素的信息存储起来,这里只添加一个元素说明(代码太长QAQ)(因为没有做后台,所以这里使用了静态数据)
var movieInfo = [
{
img:'/static/img/gunlun2.png',
title:'白蛇:缘起',
director:["黄家康","赵霁"],
actor:["张喆","杨天翔","唐小喜","刘紫玲"],
score:'7.9',
year:'2019',
saw_count:'23142',
want_count:'45421',
ratings_count:'20128',
content: '幽暗洞中,白蛇(张喆 配音)苦苦修炼却不得其法,小青见此情景,将发髻上的碧玉簪子取下,令白蛇攥在手中。那一刻,五百年前的记忆瞬间苏醒。五百年前,晚唐君主昏聩庸碌,掌握邪术的国师只手遮天,命令天下百姓捕蛇修法。为了拯救族群,白蛇冒险行刺,结果却遭遇挫败,还失去了记忆。当她再度醒来,发现自己被一个专门捕蛇的村落所救下,而那个胆小却善良的青年许宣(杨天翔 配音)则吸引了白蛇的注意。与此同时,国师派出爪牙四处追寻白蛇的下落,而蛇族更误解白蛇叛逃人类,接二连三派出杀手。五百年后的一段姻缘,早在这乱世之间便已缔结……',
postId:'0',
},
之后在要调用的页面中引入data数组文件,并将数据储存在该页面的数组post_key中
var moviesInfo = require('../../data/movieInfo.js');
Page({
data: {
},
onLoad: function (options) {
this.setData({
posts_key: moviesInfo.postList
})
},
})
然后就可以在wxml布局中,使用wx:for="{{posts_key}}"循环调用数组中的元素进行输出!wx:for-item="item"将post_key设置为别名item
<block class="movie-list-ul" wx:for="{{posts_key}}" wx:for-item="item" wx:key="*this"> <view class="movie-list-li" bindtap="jumpBtn" data-postId='{{item.postId}}'> <view class="item-top"> <image src='{{item.img}}'></image> </view> <view class="item-bottom"> <view>{{item.title}}</view> <text>{{item.score}}</text> </view> </view> </block>
·布局和样式上的一些建议
在微信小程序中可以把一个<view></view>当做一个盒子,举个栗子(以下为html的代码)
<view class="movie-list-li" bindtap="jumpBtn" data-postId='{{item.postId}}'> <view class="item-top"> <image src='{{item.img}}'></image> </view> <view class="item-bottom"> <view>{{item.title}}</view> <text>{{item.score}}</text> </view> </view>
像这张图,布局就是一个盒子中再分上下两个盒子,上盒子装了个图片,下盒子装了片名和评分。当然要做出图下的效果,需要样式的支持(wxss)。在wxml中,给每一个view取名 class=“xxx”或id=“xxx”,在wxss中就可以.xxx{}或#xxx{}对这个盒子进行样式的设置(这里不得不再说一句,flex布局天下第一)
·页面之间的跳转——wx.navigateTo({ })
在popular页面中列出了很多电影,为每一个电影盒子添加一个bindtap="xx"事件,利用函数名为xx的function进行页面跳转,核心代码为
jumpBtn:function(options){
var postId = options.currentTarget.dataset.postid;
wx.navigateTo({
url: '/pages/moviemore/moviemore?id='+postId,
})
},
wx.navigateTo({ })的功能是跳转到指定的路径,我在电影信息数组中为每一个电影添加了一个标识元素postid,即可利用postid区分每一个电影详情页面(影评和影评详情原理也是如此)
·收藏功能
这一块使用了本地缓存,利用标志数组的思想来判断这个id的电影是否被收藏,以此来显示收藏标志的不同状态
var postsCollected = wx.getStorageSync("posts_collected");
if (postsCollected) {
var postCollected = postsCollected[postId]//进入详情页面时,加载该页面的collocted状态并setData
this.setData({
collected: postCollected
})
} else {
var postsCollected = {};//如果没有该页面的状态,则将该postid位置的collocted状态定为false(这世界,我来过~)
postsCollected[postId] = false;
wx.setStorageSync("posts_collected", postsCollected)
}
},
收藏按钮上设置了一个bindtap属性名为onColletionTap的点击事件,通过异步模式(不用等待上一个操作结束,防止耗时过长的操作导致程序卡死)进行收藏和未收藏两种状态的改变,并更新本地缓存,最后的吐司为跳出一个提示框进行操作结果汇报
onColletionTap: function (event) { this.getPostsCollectedAsy();//异步收藏 }, // 异步收藏存储 getPostsCollectedAsy: function () { var that = this; wx.getStorage({ key: 'posts_collected', success: function (res) { var postsCollected = res.data; var postCollected = postsCollected[that.data.currentPostId]; // 收藏变成未收藏,未收藏变成收藏 postCollected = !postCollected; postsCollected[that.data.currentPostId] = postCollected; //更新缓存 // 吐司 that.showToast(postsCollected, postCollected) }, }) }, // 吐司 showToast: function (postsCollected, postCollected) { wx.setStorageSync('posts_collected', postsCollected); //更新数据绑定变量,从而实现切换图片 this.setData({ collected: postCollected }) wx.showToast({ title: postCollected ? '收藏成功' : '取消成功', duration: 800, icon: "success" }) },
·收藏页面的实现
收藏页面的功能是查看当前收藏了哪些电影/影评,原理为获取本地缓存,然后遍历电影元素数组,将存在于本地缓存数组中且收藏属性为true的postid所对应的电影元素组合成一个新的数组,将该数组展示出来实现
MovieRefresh:function(options){ var postlist=moviesInfo.postList var array=new Array() console.log(postlist) var postsCollected = wx.getStorageSync("posts_collected"); for(var i=0;i<postlist.length;i++){//核心代码 if(postsCollected[i]==true) array.push(postlist[i]); } this.globalData.moviearray=array console.log(this.globalData.moviearray) },
这里将整合后的数组(moviearray:[],talkarray:[])在app.js中设置,设为全局变量,并将更新这两个数组的函数MovieRefresh和TalkRefresh设为全局函数,以供子页面favorite调用。当进入收藏页面时,onload函数调用两个全局函数,为本地数组赋值
onLoad: function (options) { app.MovieRefresh() app.TalkRefresh() // console.log(app.globalData.moviearray) this.setData({ moviearray: app.globalData.moviearray, talkarray: app.globalData.talkarray }) },
如果onload执行过后又进行了收藏的变动,使用微信小程序的下拉刷新操作再调用一次onload函数即可刷新收藏列表
onPullDownRefresh: function () { this.onLoad() },
收藏页面中电影和文章的内容切换使用了样式的切换(判断显示哪一个样式)
changeViewType: function(e) { var data = e.currentTarget.dataset this.setData({ show: data.type,//show的初值为'movie_favorite'
})
}
<view class="tab-header"> <view class="tab-header-item {{show == 'movie_favorite' ? 'tab-header-active' : ''}}" data-type="movie_favorite" bindtap="changeViewType">电影</view> <view class="tab-header-item {{show == 'talk_favorite' ? 'tab-header-active' : ''}}" data-type="talk_favorite" bindtap="changeViewType">文章</view> </view>
·历史记录
历史记录的功能是查看自己浏览了哪些电影、影评(有顺序),原理是访问一个电影页面时,将该电影页面的postId存入本地缓存数组(第一次加载会新建数组),如果该id已经在数组中了,则将其删除,再将其添加到数组头部
var historyslist = wx.getStorageSync("historys_list"); if(!historyslist){ var history=this.data.history; wx.setStorageSync('historys_list', history); } for(var i=0;i<historyslist.length;i++){ if(historyslist[i]==postId) historyslist.splice(i,1); } historyslist.unshift(postId); console.log("history:"+historyslist); wx.setStorageSync('historys_list', historyslist);
之后的数值传递和页面展示和收藏类似,也是将整合后的数组(moviehistoryarray:[],talkhistoryarray:[])在app.js中设置,设为全局变量,并将更新这两个数组的函数MovieHistoryRefresh和TalkHistoryRefresh设为全局函数,以供子页面history调用。当进入历史页面时,onload函数调用两个全局函数,为本地数组赋值
·相册和皮肤
这两个功能基本沿用了源代码,原理也比较简单,相册利用tempfilePath读取本地文件并将其存入本地缓存,这个存值的存值形式如下,是小程序临时文件路径,该路径只在小程序中有效,在浏览器中无法打开
皮肤功能则是读取了本地文件skinList,其中已经写好了皮肤样式的数据(图片来自于img包)
·总结
一下子碰到一个从未接触过的项目,我的内心是微笑(崩溃)的。起初的学习很难,拿到别人的代码无从入手,原因在前言中已提到。碰到这种情况,也许自己从0开始脚踏实地写一个是不错的选择,也许直接啃他人完整代码碰到的困难level是5,那自己从新开始写碰到的困难level也许就是1。从解决小困难开始,慢慢理解微信小程序的书写过程,之后再碰到level5的困难,也许就能通过不断阅读、查百度解决了(收藏功能就是我一开始搞不懂的内容,但是最后我把它做到了我的代码中)。这个微信小程序很粗糙,因为一开始理解不了API的调用,使用了静态数据测试;因为没有配置域名(没有服务器)而不能进行后台操作,使用了本地缓存。不过至少搞懂了微信小程序是个什么样的东西,之后的学做,会慢慢的用上API,学更多的JS功能实现,总之要学的东西还很多,上下而求索。
·未解决的困难
在手机测试中会出现图片缺失的情况,网上所列出的情况一一排除后还是未解决这个问题,而开发工具中测试正常
题外话:弟弟丁嘉诚一路平安