1. 程式人生 > >移動開發 微信小程式,一個有侷限的類似 React Native 輪子!

移動開發 微信小程式,一個有侷限的類似 React Native 輪子!

先丟擲結論:微信小程式就是一個類似RN的輪子,可以快速開發,有一定的適用場景,但是也有其侷限性。

本文針對微信小程式的示例程式碼進行分析,告訴大家:

微信小程式到底提供了什麼?

開發微信小程式方便麼?

微信小程式具體適用場景?

最後還自作主張的說了點對於微信小程式的個人觀點。

微信小程式都提供了什麼?

微信小程式主要為我們提供了兩部分東西:底層API 和 元件,不僅如此,微信小程式還引入新的檔案格式。

引入了新的檔案格式

微信小程式並不是傳統意義的H5頁面,微信定義了新的檔案格式,然後對這些檔案做編譯解析,所以微信小程式是原生應用!是基於微信的原生應用!微信正式嘗試做一個OS!

微信小程式元件

上圖是一個wx-action-sheet元件,檔案應用了新的字尾。

其中wxml功能和HTML類似,wxss功能和CSS類似,JS包含元件邏輯。這點是不是和RN/weex很像?

微信提供了一套基礎元件庫

微信為微信小程式提供了一套基礎元件庫,可以滿足開發的基礎開發需求,從而實現簡單的快速開發,至於這些基礎元件支援多大程度的自定義,以及能否滿足實際專案的需求,留給後續開發者去體驗吧。

基礎元件庫主要分為四類:

控制元件(controller) 主要包括:

action-sheet / button / searchbar / modal / navigator / drawer

表單(form) 主要包括:

checkbox / radio / form , selector / switch / slider / input / label / picker

媒體(media) 主要包括:

image / audio / video

檢視(view) 主要包括:

progress / toast / scroll-view / text / view / mask / icon / spinner / swiper / slide-tab

恩,這些元件不用介紹大家也都知道大概是什麼功能了,幾乎是每個UI元件庫都必備的。以後大家應該都要基於這個元件庫去開發具體的產品,和RN/weex不同的是,WX應該只能基於微信提供的元件進行個性化封裝了,而不能基於系統元件進行個性化封裝,原因很簡單,因為微信就是一個“系統”。

我們挑一個稍微複雜的元件示例來分析分析:

// wx-picker.wxml檔案
<view class="page">
    <view class="page__hd">
        <text class="page__title">picker</text>
        <text class="page__desc">選擇器</text>
    </view>
    <view class="page__bd">
        <view class="section">
            <view class="section__title">地區選擇器</view>
            <picker bindchange="bindPickerChange" value="{{index}}" range="{{array}}">
                <view class="picker">
                    當前選擇:{{array[index]}}
                </view>
            </picker>
        </view>
        <view class="section">
            <view class="section__title">日期選擇器</view>
            <picker mode="date" value="{{date}}" start="2015-09-01" end="2017-09-01" bindchange="bindDateChange">
                <view class="picker">
                    當前選擇: {{date}}
                </view>
            </picker>
        </view>
    </view>
</view>

是的,所有的標籤都是自定義標籤,進一步正式了微信小程式應該是原生應用,元件使用很簡單,所以適合快速開發。

// wx-picker.js 檔案
Page({
  data: {
    array:["中國","美國","巴西","日本"],
    index:0,
    date:"2016-09-01"
  },
  bindPickerChange: function(e) {
    console.log('picker傳送選擇改變,攜帶值為', e.detail.value)
    this.setData({
      index: e.detail.value
    })
  },
  bindDateChange:function(e){
    this.setData({
      date:e.detail.value
    })
  },
  bindTimeChange:function(e){
    this.setData({
      time:e.detail.time
    })
  }
})

也很清晰,通過this.setData來設定屬性,實現action-sheet的顯示與隱藏切換,React的感覺,連API都很像。

// wx-picker.wxss
.picker{
    padding: 13px;
    background-color: #FFFFFF;
}

可以重新設定微信小程式的元件樣式,和CSS很相似,輕量簡潔。

底層API

沒有提供底層API的基礎元件庫都是流氓庫,有了底層API才能開發真正的原生應用,才能做更多豐富的功能。

其中底層API包括:

animation / backgronud-audio / canvas / download-file / file / get-location / get-network-type / get-system-info / get-user-info / image / login / navigation-bar-loading / navigator / on-accelerometer-change / on-compass-change / open-location / pull-down-refresh / request / request-payment / set-navigation-bar-title / storage / upload-file / voice / web-socket

從名字也能看出大概,提供了比較完整的API,能夠開發更豐富的功能和程式。

我們仍然挑一個稍微複雜點的API使用示例來分析分析:

// image.wxml檔案
<import src="../common/header.wxml" />
<import src="../common/footer.wxml" />

<view class="container">
  <template is="header" data="{{title: 'choose/previewImage'}}"/>

  <view class="page-body">
    <view class="page-body-wrapper">
      <form bindsubmit="openLocation">
        <view class="page-body-form">
          <picker range="{{sourceType}}" bindchange="sourceTypeChange" value="{{sourceTypeIndex}}">
            <view class="page-body-form-picker">
              <view class="page-body-form-picker-key">圖片來源</view>
              <view class="page-body-form-picker-value">{{sourceType[sourceTypeIndex]}}</view>
            </view>
          </picker>
          <picker range="{{sizeType}}" bindchange="sizeTypeChange" value="{{sizeTypeIndex}}">
            <view class="page-body-form-picker">
              <view class="page-body-form-picker-key">圖片質量</view>
              <view class="page-body-form-picker-value">{{sizeType[sizeTypeIndex]}}</view>
            </view>
          </picker>
          <picker range="{{count}}" bindchange="countChange" value="{{countIndex}}">
            <view class="page-body-form-picker" style="border-bottom: none;">
              <view class="page-body-form-picker-key">數量限制</view>
              <view class="page-body-form-picker-value">{{count[countIndex]}}</view>
            </view>
          </picker>
        </view>
        <view class="images-wrapper">
          <text class="images-text">請選擇圖片</text>
          <view class="images-list">
            <block wx:for-items="{{imageList}}" wx:for-item="image">
              <image src="{{image}}" class="images-image" data-src="{{image}}" bindtap="previewImage"></image>
            </block>
            <image src="/image/plus.png" class="images-image images-image-plus" bindtap="chooseImage"></image>
          </view>
        </view>
      </form>
    </view>
  </view>

  <template is="footer" />
</view>

簡單清晰wxml,居然讓選擇圖片並預覽實現起來這麼簡單。並且可以通過簡單的template語法來引入其他wxml檔案。

// image.js 檔案
var sourceType = [ ['camera'], ['album'], ['camera', 'album'] ]
var sizeType = [ ['compressed'], ['original'], ['compressed', 'original'] ]

Page({
  data: {
    sourceTypeIndex: 0,
    sourceType: ['拍照', '相簿', '拍照或相簿'],

    sizeTypeIndex: 0,
    sizeType: ['壓縮', '原圖', '壓縮或原圖'],

    countIndex: 0,
    count: [1, 2, 3, 4, 5, 6, 7, 8, 9]
  },
  sourceTypeChange: function (e) {
    this.setData({
      sourceTypeIndex: e.detail.value
    })
  },
  sizeTypeChange: function (e) {
    this.setData({
      sizeTypeIndex: e.detail.value
    })
  },
  countChange: function (e) {
    this.setData({
      countIndex: e.detail.value
    })
  },
  chooseImage: function () {
    var that = this
    wx.chooseImage({
      sourceType: sourceType[this.data.sourceTypeIndex],
      sizeType: sizeType[this.data.sizeTypeIndex],
      count: this.data.count[this.data.countIndex],
      success: function (res) {
        console.log(res)
        that.setData({
          imageList: res.tempFilePaths
        })
      }
    })
  },
  previewImage: function (e) {
    var current = e.target.dataset.src

    wx.previewImage({
      current: current,
      urls: this.data.imageList
    })
  }
})

因為微信對這個API已經封裝得很好了,所以使用起來只需要傳入幾個引數,繫結一下回調函式即可。

// image.css 檔案
.images-wrapper {
  padding: 20rpx;
  background-color: #fff;
  margin-top: 20rpx;
}
.images-wrapper-text {
  font-size: 28rpx;
}
.images-list {
  display: flex;
  margin-top: 20rpx;
  flex-wrap: wrap;
}
.images-image {
  width: 150rpx;
  height: 150rpx;
  margin: 10rpx;
}
.images-image-plus {
  border: 1px solid #999;
}

同樣,樣式通過類似CSS的語法,從上面的rpx單位可以看出,這不是真正的CSS,我猜測是CSS的子集,類似RN。

開發微信小程式方便麼?

微信小程式的開發目錄結構

WX的開發目錄結構也很清晰簡單。

WX目錄結構

入口檔案就是最外層的 app.js , app.json , app.wxss 。

app.js 提供了入口檔案的一些初始化和繫結。

app.json 提供了專案的結構和一些專案配置,微信之所以採用app.json的模式宣告專案需要載入的頁面和元件,應該是為了方便實現雲端編譯打包然後下發到微信吧。

app.wxss 就是樣式啦。

page目錄 放你需要實現具體功能的頁面。

util 存放專案需要用到的一些工具函式。

微信小程式的部署流程

微信小程式採用的基於微信的是原生開發,安裝和使用應該都要很輕量,所以微信採用雲端編譯打包的方式,將編譯後的檔案傳送到微信上,然後微信內建的解析器會解析這個檔案並渲染。

簡而言之,微信小程式的開發體驗還算流暢,程式碼可讀性也很高,也不需要做太多新的知識儲備,但是有硬傷,後文會分析。

微信小程式適合你嗎?

這一塊就不細講了,畢竟不是我擅長的,借用網上的分析,用兩張圖片告訴你微信小程式的適用場景。

行業區分

微信小程式適合什麼

所以,微信小程式更適合用來做低頻但重要的服務,比如酒店訂閱,火車票/機票訂閱,招聘,理財等。

總結點什麼?

每次的總結都是為了更快的結束寫文章的“枯燥”過程,也為了讓大家更快的看到文章。

以下代表個人觀點,僅供參考,也歡迎討論。

從產品層面來說,值得一試!

  1. 微信提供了不錯的底層API以及還算豐富的元件庫,讓小程式可以快速開發並且擁有原生體驗,相對之前的公眾號/服務號,體驗更好。
  2. 微信流量很大,對於部分中小產品來說,是一次機會。
  3. 一些不需要使用者留存,但又是剛需的產品也許很適合,比如訂票,使用者開啟頁面,簡單選擇,然後微信支付,感覺還挺爽的。

從技術棧來說,我不喜歡!

  1. 微信小程式是基於微信生態的,而這個生態目前太不成熟。
  2. 只能在微信中執行,多半支援在瀏覽器或者其他地方執行,也就是說,並沒有減少產品的開發成本,反倒是多了一個開發流水線。
  3. 新的語法糖,開發除錯環境也不友好,開發者會有陣痛期。

YY一下,如果微信小程式的技術棧是RN而不是造一個輪子,那感覺才爽!!