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


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

ios8及部分機型下會有樣式混亂的問題,經查找,原因是缺少瀏覽器前綴,需要加prefix

解決方案見鏈接:wepy-less-autoprefix

另外:如果直接引入了.wxss文件,需要改成.less

再另:如果使用scss,使用:wepy-plugin-autoprefixer


綜述

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

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

RT,這里給幾個我認為開發過程中不爽的幾個地方,拋磚引玉。

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

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

3) 不能使用 less、jade

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

5) request 並發次數限制

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

......

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

二、什么是以及為什么使用 wepy

如果可以,請先花3、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

三、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:

待續......


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM