微信小程序實戰

分類:技術 時間:2017-01-13

微信小程序經過幾個月的內側,在今年的 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 項目列舉幾個, wepylabrador

感興趣的可以點進去看看,使用與否取決于你項目的復雜程度,你的異步操作過多 ES6 的 promise 無法滿足你的需求,ES7 的 async/await 可以幫到你,或是你的狀態過多想使用 redux,你就可以嘗試微信小程序組件化開發框架。

本例中再封裝一層框架純屬沒事找事,沒有任何意義。

總結

小程序的評價褒貶不一,與其評價它存在的意義不如看下它的適用場景,對于功能性強的 App 很合適,本例不太合適但是人家騰訊視頻可以做小程序我們就可以做,說到以后的發展如何誰都說不準,最起碼穩定性可以保證,借著寫小程序可以加深對類 vue 框架的了解,內聯的事件寫法也是今后的一個趨勢,數據的綁定類 react 的 setData,如果你之前嘗試過這兩個框架開發小程序會非常得心應手。


Tags: 微信小程序開發

文章來源:http://orangexc.xyz/2017/01/12/Wechat-small-app/


ads
ads

相關文章
ads

相關文章

ad