微信小程序框架——wepy使後感

更新:2018年1月10日15:32:22css

ios8及部分機型下會有樣式混亂的問題,經查找,緣由是缺乏瀏覽器前綴,須要加prefixhtml

解決方案見連接:wepy-less-autoprefixios

另外:若是直接引入了.wxss文件,須要改爲.lessgit

再另:若是使用scss,使用:wepy-plugin-autoprefixergithub


綜述

  • 小程序開發有哪些痛點
  • 什麼是以及如何使用 wepy
  • wepy使用注意事項
  • ......

1、小程序開發有哪些痛點

RT,這裏給幾個我認爲開發過程當中不爽的幾個地方,拋磚引玉。typescript

1) 頻繁調用 setDatasetData過程當中頁面跳閃,張老師有篇寫的很好 Page和datanpm

2) 組件化支持能力太弱(幾乎沒有)redux

3) 不能使用 less、jade小程序

4) 沒法使用 NPM 包及 ES 高級語法api

5) request 併發次數限制

6) 一個頁面對應4個文件,看的眼花繚亂

......

P.S.若是你還不瞭解如何開發小程序,那麼得抓緊看下小程序開發簡易教程了,兄得

2、什麼是以及爲何使用 wepy

若是能夠,請先花三、5分鐘看一下正經官方文檔。由於關於wepy的一切,文檔確定比我說的清楚。

如今,咱們這樣寫小程序,是否是很嗨皮呢,(cou zi shu:

<style lang="less">
    @color: #4D926F;
    .userinfo {
        color: @color;
    }
</style>
<template lang="pug">
    view(class='container')
        view(class='userinfo' @tap='tap')
            mycom(:prop.sync='myprop' @fn.user='myevent')
            text {{now}}
</template>

<script>
    import wepy from 'wepy';
    import mycom from '../components/mycom';

    export default class Index extends wepy.page {
        
        components = { mycom };
        data = {
            myprop: {}
        };
        computed = {
            now () { return +new Date(); }
        };
        async onLoad() {
            await sleep(3);
            console.log('Hello World');
        }
        sleep(time) {
            return new Promise((resolve, reject) => setTimeout(() => resolve, time * 1000));
        }
    }
</script>

寫到這裏我忽然發現沒什麼可寫的了,文檔都很清楚啊!MDZZ

3、wepy 使用注意事項

因爲類Vue的開發風格,使得開發效率變高了,一個頁面對應一個文件,後期維護變得更簡單了。然鵝,由於微信的種種限制以及wepy的黑魔法,致使咱們不能爲所欲爲的管理應用。

3.1 數據管理問題

組件間的數據可使用框架提供的 $emit $broast等方法,但頁面之間的數據,就須要咱們手動管理,很是麻煩且易於出錯。

就目前來看,主要有四種方案能夠選擇:

  • Gloabal 對象或Storage

    使用微信提供的`getApp()`方法,能夠在頁面間隨意訪問和改寫這個對象。
  • EventBus

    經過訂閱/發佈事件的方式,共享數據
  • Store(臨時想到)

    建立一個存儲類來管理數據,本質上和`Storage`相似,但不能直接對數據進行修改而經過action觸發數據變動。
  • wepy-redux

    其實官方仍是提供了`redux`方案,但沒有在文檔中暴露出來,使用`wepy new demo --redux`建立。

在拼車小程序中,使用的是第二種方法,按下不表。代碼詳見

關於第三種Store方案,本來我想使用mobx來管理小程序的數據,嘗試後失敗了。但本身建立一個類來管理數據,總以爲有些地方不妥,真心但願你能給個意見

Store.js ,代碼示例僅提供思路

class Store {
  constructor (initState = {}) {
    if (typeof initState !== 'object' || initState === null) {
      throw new TypeError('[Store] Init state must be a object.')
    }
    const _state = this._state = deepclone(initState)
    this.state = this._hookState(_state)
  }
   // 禁止直接修改
  _hookState (_state) {
    const state = {}
    Object.keys(_state).forEach(key => {
      if (typeof _state[key] === 'object' && _state[key] !== null) {
        _state[key] = this._hookState(_state[key])
      } else if (typeof _state[key] === 'function') {
        throw new TypeError('[Store] state cannot save function.')
      }
      Object.defineProperty(state, key, {
        enumerable: true,
        configurable: true,
        get () {
          return _state[key]
        },
        set (newVal) {
          throw new TypeError('[Store] mutate state failed. Use .mutate() to mutate state')
        }
      })
    })
    return state
  }
  mutate (fn) {
    const newState = this._state = deepclone(
      fn.apply(null, this._state)
    )
    this.state = this._hookState(newState)
  }
}
module.exports = new Store({})

3.2 數據預加載優化

10-24更新

在使用onPrefetch預查詢數據時,要注意兩點:

  • 必須在頁面層級上使用路由跳轉 => this.$navigate(url)
  • url 必須是相對路徑

背景:我在 page1 寫了一個倒計時,跳轉到 page2 後發現倒計時仍然在進行。這說明什麼呢?

這代表在小程序內即使發生跳轉,頁面的 Javascript 數據並不會從內存中消失,和咱們日常開發 H5 頁面有很大不一樣,是吧?

通常而言,咱們請求數據是在onLoad中進行,可是小程序的 page 1跳轉到 page 2,再到 page 2onLoad是存在一個 300ms ~ 400ms 的延時的(這點@張帥 的上篇文章也提到了),因此咱們白白浪費了這個時間。

wepy在這裏作了很容易被忽略的優化——

  • 預加載數據

    用於 page1 主動傳遞數據給 page2,好比 page2 須要加載一份耗時很長的數據。我能夠在 page1 閒時先加載好,進入 page2 時直接就可使用。

  • 預查詢數據

    用於避免於 redirecting 延時,在跳轉時調用 page2 預查詢。

它擴展了頁面生命週期,添加了onPrefetch事件,使得在 $redirect/$navigate之時被主動調用。同時,給onLoad事件添加了一個參數,用於接收預加載或者是預查詢的數據,以下:

// params
// data.from: 來源頁面,page1
// data.prefetch: 預查詢數據
// data.preload: 預加載數據
onLoad (params, data) {}

預加載數據示例:

// page1.wpy 預先加載 page2 須要的數據。

methods: {
  tap () {
    this.$redirect('./page2');
  }
},
onLoad () {
  setTimeout(() => {
    this.$preload('list', api.getBigList())
  }, 3000)
}

// page2.wpy 直接從參數中拿到 page1 中預先加載的數據
onLoad (params, data) {
  data.preload.list.then((list) => render(list));
}

預查詢數據示例:

// page1.wpy 使用封裝的 redirect 方法跳轉時,會調用 page2 的 onPrefetch 方法
methods: {
  tap () {
    this.$redirect('./page2');
  }
}

// page2.wpy 直接從參數中拿到 onPrefetch 中返回的數據
onPrefetch () {
  return api.getBigList();
}
onLoad (params, data) {
  data.prefetch.then((list) => render(list));
}

3.3 數據上報(並無作)

MTA是騰訊自家的數據分析平臺,在小程序發佈後MTA平臺很快的就支持了小程序的數據上報。所以手機充值選擇MTA作爲數據上報平臺,具體步驟以下:

在MTA官網註冊應用;

在mp平臺,小程序開發設置中,將https://pingtas.qq.com添加爲可信域名;

安裝 mta-analysis 模塊:npm install mta-analysis --save

在 app.wpy 中添加初始化代碼。

import wepy from 'wepy';
import mta from 'mta-analysis';

export default class extends wepy.app {
   onLaunch() {
       mta.App.init({
          "appID":"xxxx", // 註冊後獲得的appID
          "eventID":"xxxx", // 註冊後獲得的eventID
          "statPullDownFresh":true, // 使用分析-下來刷新次數/人數,必須先開通自定義事件,並配置了合法的eventID
          "statShareApp":true, // 使用分析-分享次數/人數,必須先開通自定義事件,並配置了合法的eventID
          "statReachBottom":true // 使用分析-頁面觸底次數/人數,必須先開通自定義事件,並配置了合法的eventID
       });
   };
}

這樣就完成了MTA的初始化工做,在每一個頁面的 onLoad 事件中加入 init 事件完成頁面的上報。

export default class Index extends wepy.page {
   onLoad () {
       mta.Page.init();
   };
}

在 app.wpy 中加入報錯上報。

export default class extends wepy.app {
   onError () {
       mta.Event.stat("error",{});
   };
}

以及在其它業務邏輯代碼上加入一些自定義事件上報,好比下單上報,支持上報等等。

mta.Event.stat("payed",{});

3.4 Integrating TypeScript

仍是算求 D:

待續......

相關文章
相關標籤/搜索