博客班級 | 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功能實現,總之要學的東西還很多,上下而求索。
·未解決的困難
在手機測試中會出現圖片缺失的情況,網上所列出的情況一一排除后還是未解決這個問題,而開發工具中測試正常
題外話:弟弟丁嘉誠一路平安