小程式開發前的準備工作

張牧歌發表於2019-05-09

磨刀不誤砍柴工,在開發之前做好準備工作可以大大提升開發效率、減少冗餘程式碼,這篇文章結合自己做過的幾個小程式的經驗做一個總結。


相關參考 vant-weapp武裝你的小程式——開發流程指南

著手開發小程式前都有哪些工作要準備?

  • 重寫小程式Page、Component函式
  • Request方法封裝
  • Router路由封裝
  • Less的使用
  • Util的封裝

為什麼要重寫Page、Component函式?

準備開發頁面之前你是否經歷過這樣...

import store from "../utils/store";
import util from "../utils/util";
import fetch from "../utils/fetch";
import config from "../utils/config";

Page ({
  // ...  
})
複製程式碼

小程式開發前的準備工作
每個頁面都要複製貼上 我@#$%^&*


以下辦法可能會解決這些問題 並且相當舒適

  1. 建立Init.js 並引入到app.js裡, 像這樣⬇️
require('./utils/Init.js');

App({
  onLaunch: function () {}
})
複製程式碼
  1. 重寫Page、Component函式

函式重寫思考:小程式屬於單頁面應用,全域性的頁面元件註冊全依靠Page、Component函式,實際上就是呼叫了一個函式 傳入了一個物件,那我們能不能在函式呼叫前,對引數做一些小動作呢?

先來試驗一下

編輯Init.js

// 函式劫持 重寫註冊函式
let originPage = Page;
Page = (opt) => {
    // 在傳入Page函式的引數中 新增一個util物件
    opt.util = {
        test () {
            return 1;
        }
    }
    return originPage(opt);
}
複製程式碼

在頁面onLoad方法中測試一下

Page({
  data: {
  },
  onLoad: function () {
    console.log(this.util.test())
  }
})
複製程式碼

結果輸出如下

輸出結果

執行成功!接下來你應該懂我的意思 塞他!小程式開發前的準備工作

編輯Init.js

import _store from "./store";
import _util from "./util";
import _fetch from "./fetch";

let originPage = Page;
Page = (opt) => {
    // 把建立好的工具類引入opt引數內
    opt = {
        ...opt,
        _store,
        _util,
        _fetch
    }
    return originPage(opt);
}
複製程式碼

然後在頁面中輸出一下this關鍵字

嗯...終於不用引亂七八糟的東西了

注意!Component函式中如果也這麼寫 元件例項中並不會出現新增的物件 像這樣 ⬇️

// Init.js
import _store from "./store";
import _util from "./util";
import _fetch from "./fetch";

let originComponent = Component;
Component = (opt) => {
    opt.util = {
        test() {
            return 1
        }
    }
    return originComponent(opt);
}

------------
// components/img/index.js
Component({
  attached () {
    this.test();
  },
  methods: {
    test() {
      console.log(this.util)
    }
  }
})

複製程式碼

小程式開發前的準備工作
執行結果

但這就不代表我沒有辦法 小程式開發前的準備工作

編輯init.js 重寫component部分

Component = (opt) => {
  // Component函式的options無法直接插入引數 只能在某個生命週期函式被呼叫時動態賦值
  let originAttached = opt.attached || function () {};
  opt.attached = function(e) {
    this.util = {
      a() {
        return 1;
      }
    };
    return originAttached.apply(this);
  }
  return originComponent(opt)
}
複製程式碼

小程式開發前的準備工作
執行結果

最終把下面的各種工具類新增上之後 簡單寫個請求、跳轉 大概就是這個樣子⬇️

Page({
  data: {
  },
  onLoad: function ({ goodId }) {
    this._fetch({
      url: "getGoods",
      data: { goodId }
    }).then(res => {
      if (res.length) {
        this._router.go("detail", { firstGoodsId: res[0].id })
      }
    })
  }
})
複製程式碼

小程式開發前的準備工作


以下是工作中各種用到的封裝

Request方法封裝

wx.request方法封裝點:請求狀態、錯誤統一處理,以當前上下文可控制頁面所有需要請求狀態的元件

Fetch.js

const host = {
  Dev: "http://test.com"
}

const api = {
  getUserInfo: "...",
  getGoods: "..."
}

export default function ({ url, data, showLoading = false }) {
  let self = this;
  changeFetchState(self, true);
  showLoading && wx.showLoading({ title: showLoading })
  return new Promise((resolve, reject) => {
    const options = {
      url: host.Dev + api[url],
      method: "POST",
      header: { "content-type": "application/json" },
      data,
      success: ({ data }) => {
        resolve(data.data, data);
      },
      fail: err => {
        reject(err);
      },
      complete() {
        changeFetchState(self, false);
        showLoading && wx.hideLoading();
      }
    };

    wx.request(options);
  })
}
// 以當前作用域呼叫,可控制頁面需要請求狀態的元件
function changeFetchState (self, state) {
  self && self.setData({ _fetchState: state });
}
複製程式碼

Router路由封裝

規範路由管理、傳參,以{key:value}形式定義路由,重新封裝路由跳轉方法,方便呼叫。

Router.js

// 路由定義
const routePath = {
  "index": "/pages/index/index",
  "detail": "/pages/detail/index",
  "service": "/pages/service/index"
};
// tabbar名單 特殊處理
const tabbar = ['index', 'service']

const Router = {
  // 引數轉換
  parse: function (data) {
    if (!data) return '';
    let tempArr = [];
    for (let key in data) {
      tempArr.push(`${key}=${encodeURIComponent(data[key])`);
    }
    return '?' + tempArr.join('&');
  },
  go: function (path = 'index', params = null, duration = 0) {
    setTimeout(() => {
      const isTabbar = tabbar.indexOf(path) == -1;
      // 如果是tabbar用switchTab方法切換
      wx[isTabbar ? 'navigateTo' : 'switchTab']({
        url: routePath[path] + this.parse(params),
      })
    }, duration * 1000);
  },
  goBack: function (delta = 1, duration) {
    setTimeout(() => {
      wx.navigateBack({ delta })
    }, duration * 1000)
  }
}

export default Router;
複製程式碼

Less的使用

首先全域性安裝less外掛 npm install less -g

步驟1
WebStorm -> Preferences
Tools -> File Watchers -> 新建監聽檔案選擇Less -> 【重點】設定Output檔案格式為wxss


Util通用類封裝

自己常用的工具大概有這幾種:Storage儲存、頁面地址取參、獲取當前上下文等等,通常Util一下也想不全都是在開發中邊用邊寫,以下幾個為例子。

Util.js

// Storage相關
function getStore (name1, name2) {
  if (!name1) return false;
  let baseStore = wx.getStorageSync(name1);
  if (!baseStore) return false;
  return name2 ? (baseStore[name2] || '') : baseStore;
}
function setStore (name, value) {
  if (!name) return false;
  return wx.setStorageSync(name, value);
}
function setStoreChild (name1, name2, value) {
  if (!name1 || !name2) return false;
  let baseStore = getStore(name1) || {};
  baseStore[name2] = value;
  return setStore(name1, baseStore);
}
/**
 * 獲取資料型別
 * @param value
 * @returns {*}
 */
function getValueType(value) {
  if (typeof value === 'number') return Number;
  if (typeof value === 'string') return String;
  if (typeof value === 'boolean') return Boolean;

  if (value instanceof Object && !value instanceof Array) return Object;
  if (value instanceof Array) return Array;

  return null;
}
/**
 * 獲取當前頁面上下文
 * @returns {*}
 */
function getPageContext() {
  var pages = getCurrentPages();
  return pages[pages.length - 1];
}
/**
 * 獲取元素
 * @param classItem
 */
function $select(className, cb) {
  const query = wx.createSelectorQuery().in(this)
  query.select(className).boundingClientRect()
  query.selectViewport().scrollOffset()
  query.exec(function (res) {
    cb(className.substr('0') === '#' ? res[0] : res);
  })
}

module.exports = {
  getStore,
  setStore,
  setStoreChild,
  getValueType,
  getPageContext,
  $select
}
複製程式碼

小程式開發前的準備工作

相關文章