微信小程序經過幾個月的內側,在今年的 1 月 9 日正式上線,在微信通訊錄頁面就可以搜索你想找的小程序,然后在發現頁最底部就會有你曾經瀏覽過的小程序的入口。
一番體驗后比橙子想象的效果好的多,所以自己起手也寫了一個。下面具體介紹細節。
想寫小程序的大家都知道只有企業賬戶可以發布,但是開發卻不需要企業賬號,但是我們需要實名認證我們的小程序賬號。
注冊賬號
直接給官網鏈接 https://mp.weixin.qq.com/debug/wxadoc/introduction/?t=201718#注冊小程序帳號
注意:沒有企業認證記得在 選擇主體類型 時選擇-gt;其他組織,組織名稱自己起,機構代碼只要符合它的規則就行(輸入框下有提示直接復制粘貼),公章的掃描件上傳隨意圖片即可,管理員信息務必填寫真實信息(切記)
開發工具
在官網給出了下載入口 https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/download.html?t=201715
安裝后會有掃碼登錄,然后按照這個鏈接執行 https://mp.weixin.qq.com/debug/wxadoc/introduction/?t=201718#登錄
記得你在官網注冊成功后小程序的 AppID,這里不用選擇本地開發目錄,為了起手方便當你添加項目時會問你是不是使用它的初始化模板(點擊使用)。
現在不出差錯的話你的頁面會出現 你的 頭像、用戶名、Hello world
如果顯示正常,恭喜你環境配置成功
有時卻不是那么順利,橙子在打開初始化項目報錯 Failed to load resource: net::ERR_NAME_NOT_RESOLVED
如果你有相同的錯誤解決辦法很簡單,關掉你的 vpn 即可(并不是所有 vpn 均存在問題,因為橙子咨詢其他人的 vpn 沒關也不會產生這個問題),記得重啟你的開發者工具。
起步
如果你了解幾種文件的作用可以跳過此步,不了解的可以看下官網起步教程, https://mp.weixin.qq.com/debug/wxadoc/dev/?t=201715
然后在上面鏈接仔細過一遍 框架、組件、API(切記認真閱讀)
也許你會問官網給的那么詳細我寫這個文章的意義在哪?
問的好,如果官網能給我一個完整的小程序我也不會費周折去自己寫,官網的 API 固然重要,都是人家開發的我們無權篡改,本文的目的是盡量讓大家少踩坑。
實戰
自己定義下產品詳情,一個展示視頻的 app,列表與播放頁,非常簡單的例子,上手簡單
這里涉及到網絡請求,首先去管理平臺,最下面的設置里配置你的服務器域名,你自己有接口最好,不必走本例的接口,根據官方文檔你可以寫出自己的程序
另外值得一提的就是 V2EX,知乎日報,豆瓣等都提供外部接口供大家使用,沒有接口的可以用本例的 https://api.idarex.com(填寫到**request合法域名**即可),每月只能修改三次謹慎使用
兩個頁面構成?倒也沒那個必要,增加整個小程序的體積,而且跨頁面傳輸數據多一層邏輯,這里采用 wx:if
實現條件渲染來實現。
我們只需要保留 index
文件夾下的文件
從全局文件改起 log 部分可以選擇保留,獲取用戶信息部份暫時用不到
app.js
App({ onLaunch: function(){ //調用API從本地緩存中獲取數據 var logs = wx.getStorageSync('logs') || [] logs.unshift(Date.now()) wx.setStorageSync('logs', logs) } })
全局的配置文件只需要 window 的基礎配置,這里修改 navigationBar 的內容樣式
app.json
{ quot;pagesquot;:[ quot;pages/index/indexquot;, quot;pages/logs/logsquot; ], quot;windowquot;:{ quot;backgroundTextStylequot;:quot;lightquot;, quot;navigationBarBackgroundColorquot;: quot;#f8ac09quot;, quot;navigationBarTitleTextquot;: quot;敢玩原創視頻quot;, quot;navigationBarTextStylequot;:quot;blackquot; } }
全局樣式沒有太多規則,這里避免后期的計算誤差問題注意兩點
app.wxss
/* 讓頁面高占滿全屏,類似給 html 設置 100% 讓子集元素的百分比為全屏的百分比 */ page { height: 100%; } /* border-box 非常方便我們計算寬高 */ view, text { box-sizing: border-box; } .container { height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: space-between; box-sizing: border-box; }
注: *
選擇器無效,強烈推薦使用 flex 進行布局,許多場景下普通的布局規則無效
主頁上面一個輪播,輪播圖改變時劇集也發生變化,默認的 player 隱藏,頁面結構如下
pages/index/index.wxml
lt;viewclass=quot;containerquot;gt; lt;swiperclass=quot;swiperquot;bindchange=quot;changeAlbumquot;indicator-dots=quot;{{indicatorDots}}quot;autoplay=quot;{{autoplay}}quot;duration=quot;{{duration}}quot;gt; lt;blockwx:for=quot;{{albums}}quot;wx:key=quot;titlequot;gt; lt;swiper-itemclass=quot;swiper-itemquot;gt; lt;imagesrc=http://www.tuicool.com/articles/quot;{{item.cover}}quot;class=quot;slide-imagequot;/gt; lt;/swiper-itemgt; lt;/blockgt; lt;/swipergt; lt;scroll-viewclass=quot;scroll-viewquot;scroll-y=quot;truequot;scroll-top=quot;{{scrollTop}}quot;gt; lt;blockwx:for=quot;{{videoList}}quot;wx:key=quot;idquot;gt; lt;viewclass=quot;video-itemquot;data-id=quot;{{index}}quot;catchtap=quot;playVideoquot;gt; lt;imagesrc=quot;{{item.cover}}quot;class=quot;video-coverquot;gt;lt;/imagegt; lt;viewclass=quot;video-infoquot;gt; lt;textclass=quot;video-titlequot;gt;{{item.title}}lt;/textgt; lt;textclass=quot;video-play-countquot;gt;{{item.play_count}}次播放lt;/textgt; lt;/viewgt; lt;/viewgt; lt;/blockgt; lt;/scroll-viewgt; lt;viewclass=quot;playerquot;wx:if=quot;{{playerShow}}quot;gt; lt;iconclass=quot;closequot;type=quot;clearquot;size=quot;45quot;color=quot;rgba(255, 255, 255, 0.5)quot;catchtap=quot;closeVideoquot;/gt; lt;videoclass=quot;videoquot;src=quot;{{videoUrl}}quot;autoplay=quot;truequot;/gt; lt;textclass=quot;player-titlequot;gt;第{{videoIndex 1}}集:{{videoTitle}}lt;/textgt; lt;viewclass=quot;handle-barquot;gt; lt;buttonclass=quot;pre-btnquot;catchtap=quot;preVideoquot;gt;上一集lt;/buttongt; lt;buttonclass=quot;next-btnquot;catchtap=quot;nextVideoquot;gt;下一集lt;/buttongt; lt;/viewgt; lt;textclass=quot;msgquot;gt;沒看過癮?返回主頁側滑看更多炸裂專輯lt;/textgt; lt;/viewgt; lt;/viewgt;
注: wx:for
建議寫到外層的 block 標簽中,而且必須加上 wx:key
定義你的標志字段,否則報錯。綁定事件如果為 tap,強烈建議使用 catchtap
而不采用 bindtap
,除非有特殊的冒泡觸發事件需求,否則使用 catchtap
避免冒泡。這里為什么使用 wx:if
(首屏加載塊但切換成本大) 而不用官方建議的 hidden(首屏加載慢但切換成本小),在這個場景 player 層會頻繁切換適合使用 hidden,但 hidden 存在 bug,它隱藏不掉 view 層里面包含的元素,video 標簽依然暴露在且占據空間,破壞了我們的整體布局,實際測試 wx:if
在微應用場景無任何性能問題。
看下整體的樣式文件
pages/index/index.wxss
.swiper { width: 100%; height: 40%; } .swiper-item { display: flex; justify-content: center; background: #dedede; } .slide-image { width: 50%; height: 100%; } .scroll-view { height: 60%; } .video-item { display: flex; flex-direction: row; justify-content: flex-start; height: 115px; padding: 10px; background: rgba(255, 255, 255, 0.9); border-bottom: 1px solid #dedede; } .video-cover { display: block; width: 150px; height: 95px; border-radius: 5px; } .video-info { display: flex; flex: 1; flex-direction: column; justify-content: space-between; padding: 5px 0 5px 20px; } .video-title { width: 100%; line-height: 1.5; font-size: 14px; } .video-play-count { width: 100%; display: flex; justify-content: flex-end; font-size: 12px; } .player { width: 100%; height: 100%; position: absolute; top: 0; left: 0; z-index: 100; background: #000; } .player-title { width: 100%; padding-left: 10px; border-left: 3px solid #ccc; overflow:hidden; white-space:nowrap; text-overflow:ellipsis; color: #fff; font-size: 14px; } .close { position: fixed; top: 20px; right: 20px; } .video { width: 100%; margin-top: 80px; } .handle-bar { display: flex; flex-direction: row; justify-content: space-around; margin-top: 20px; } .pre-btn, .next-btn { width: 40%; background: #f49d0d; color: #673806; } .button-hover { background-color: #f9bd3a; } .msg { width: 216px; margin-left: -108px; position: fixed; bottom: 10px; left: 50%; font-size: 12px; color: #999; }
注:樣式以 flex 百分比做整體布局,具體塊級元素和字體給 px 值
pages/index/index.js
//獲取應用實例 var app = getApp() Page({ data: { albums: [], videoList: [], scrollTop: 0, indicatorDots: true, autoplay: false, duration: 1000, playerShow: false, videoUrl: '', videoTitle: '', videoIndex: 0 }, changeAlbum: function(e){ this.setData({ videoList: this.data.albums[e.detail.current].videos, scrollTop: 0 }) }, playVideo: function(e){ let index = e.currentTarget.dataset.id this.setData({ videoTitle: this.data.videoList[index].title, videoUrl: this.data.videoList[index].play_url, playerShow: true, videoIndex: index }) }, closeVideo: function(){ this.setData({ videoUrl: '', playerShow: false }) }, preVideo: function(){ let index = this.data.videoIndex if (index === 0) { wx.showToast({ title: '前面沒有啦!', icon: 'loading', duration: 10000 }) setTimeout(function(){ wx.hideToast() },1000) } else { this.setData({ videoTitle: this.data.videoList[index - 1].title, videoUrl: this.data.videoList[index - 1].play_url, videoIndex: index - 1 }) } }, nextVideo: function(){ let index = this.data.videoIndex if (index === this.data.videoList.length - 1) { wx.showToast({ title: '后面沒有啦!', icon: 'loading', duration: 10000 }) setTimeout(function(){ wx.hideToast() },1000) } else { this.setData({ videoTitle: this.data.videoList[index 1].title, videoUrl: this.data.videoList[index 1].play_url, videoIndex: index 1 }) } }, onReady: function(){ var that = this wx.request({ url: 'https://api.idarex.com/www/index', success (res) { that.setData({ albums: res.data.columns, videoList: res.data.columns[0].videos }) } }) } })
注: onReady
取代 onLoad
安卓 6.4.3 存在 bug,事件的傳參要通過 event.currentTarget.dataset
傳遞在 wxml 里通過定義 data-xxx 屬性綁定 key,其它代碼簡單易懂沒有高級語法,可以直接復制粘貼然后自定義修改
最后的效果如下
進階
如果你的小程序擁有一定的規模你一定會嘗試,模塊化開發、ES6,7 的高級語法、第三方庫等等。
實現原理就是按模塊化的開發去寫,npm 去安裝依賴庫,然后編譯成微信開發者工具可以識別的項目結構
映著需求簇生的 Github 項目列舉幾個, wepy 、 labrador
感興趣的可以點進去看看,使用與否取決于你項目的復雜程度,你的異步操作過多 ES6 的 promise 無法滿足你的需求,ES7 的 async/await 可以幫到你,或是你的狀態過多想使用 redux,你就可以嘗試微信小程序組件化開發框架。
本例中再封裝一層框架純屬沒事找事,沒有任何意義。
總結
小程序的評價褒貶不一,與其評價它存在的意義不如看下它的適用場景,對于功能性強的 App 很合適,本例不太合適但是人家騰訊視頻可以做小程序我們就可以做,說到以后的發展如何誰都說不準,最起碼穩定性可以保證,借著寫小程序可以加深對類 vue 框架的了解,內聯的事件寫法也是今后的一個趨勢,數據的綁定類 react 的 setData,如果你之前嘗試過這兩個框架開發小程序會非常得心應手。
Tags: 微信小程序開發
文章來源:http://orangexc.xyz/2017/01/12/Wechat-small-app/