1、介紹
WePY 是 騰訊 參考了Vue 等框架對原生小程序進行再次封裝的框架,更貼近於 MVVM 架構模式, 並支持ES6/7的一些新特性。
2、使用
npm install -g wepy-cli //全局安裝或更新WePY命令行工具(wepy腳手架): wepy-cli wepy -v //查看wepy-cli版本 wepy init standard <projectName> //新建wepy小程序項目,1.7.0之前的版本使用:wepy new myproject,安裝項目翻譯一下即可 wepy list //查看項目模板 cd <projectName> //切換至項目目錄 npm install //安裝依賴 wepy build --watch //開啟實時編譯
3、規范
①代碼規范
wepy和原生標簽一樣
自定義組件名盡量避開原生組件名、wepy的輔助標簽repeat
方法名、變量名盡量使用駝峰命名
文件后綴為.wpy
支持ES6/ES7的一些新特性
繼承了wx對象方法,wepy中沒有wx對象,盡量不要用到此方法,打包時容易報錯
②數據綁定
//原生小程序 this.setData({xxx:xxx}); //wepy data={aaa:''} this.aaa = 'aaa'; //wepy 在異步函數中更新數據的時候,必須手動調用$apply方法,才會觸發臟數據檢查流程的運行 this.$apply();
③事件綁定以及時間傳參
<view @tap="click"></view> // 原 bindtap="click"(省略了.default后綴 )綁定小程序冒泡型事件 <view @tap.stop="click"></view> // 原catchtap="click" 綁定小程序捕獲型事件,如catchtap <view @tap.capture="click"></view> // 原 capture-bind:tap="click" <view @tap.capture.stop="click"></view> // 原 capture-catch:tap="click" <!--事件傳參--> <view @tap="click({{index}})"></view> // 原bindtap="click" data-index={{index}}
④框架默認對小程序的API提供了Promise處理,可以直接調用async/await直接開發
// 原生代碼: wx.request({ url: 'xxx', success: function (data) { console.log(data); } }); // WePY 使用方式, 需要開啟 Promise 支持,參考開發規范章節 wepy.request('xxxx').then((d) => console.log(d)); // async/await 的使用方式, 需要開啟 Promise 和 async/await 支持,參考 WIKI async function request () { let d = await wepy.request('xxxxx'); console.log(d); }
//需要開啟Promise的解釋
//1、進入項目目錄,安裝polyfill
npm install wepy-async-function --save
//2、在app.wpy中導入polyfill
import 'wepy-async-function';
//3、在app.wpy中使用promiss
constructor () { super(); this.use('promisify'); }
//4、判斷是否引入成功
onLaunch() { console.log('on launch'); let mypro = new Promise((resolve, reject) => { setTimeout(() => { resolve(123); }, 2000); }); mypro.then((r)=>{ console.log(r); }) }
//重啟編譯
//打印出內容即為成功
⑤computed計算屬性,類型{ [ key:string ] : function },有返回值,綁定數據使用,
data={aaa:1};
// 計算屬性aPlus,在腳本中可通過this.aPlus來引用,在模板中可通過{{ aPlus }}來插值
computed={ aPlus(){ return this.a+1 } };
⑥watcher監聽,類型{ [ key:string ] : function },監聽任何屬性更新,處理數據專用。
data={ aaa:'xxx' };
// 監聽器函數名必須跟需要被監聽的data對象中的屬性同名,
// 其參數中的newValue為屬性改變后的新值,oldValue為改變前的舊值
// 每當監聽屬性aaa改變一次,該函數就調用一次
watch={
aaa(newValue,oldValue){
console.log(`data的aaa由${oldValue}變為${newValue}`)
}
}
⑦wxs
等待學習
⑧interceptor攔截器
可以對原生api進行請求攔截,具體方法是配置api的config、fail、success、complete回調函數。
//app.wpy constructor () { //在super()是不允許的 super() //攔截request請求 this.intercept('request',{ //發出請求時的回調函數 config(res){ //對所有請求附加token res.token = token; return res; } //請求成功后的回調函數 success(res){ return res; } //請求失敗后的回調函數 fail(res){ return res; } //請求完成后的回調函數 complete(res){ return res; } }); }
4、項目目錄結構
原生小程序:app(app.js、app.json、app.wxss),page(page.js、page.json、page.wxml、page.wxss),文件必須同名。
WePY中則使用了單文件模式:app.wpy,page.wpy。
一個.wpy文件可分為三大部分,各自對應於一個標簽:
- 腳本
<script>部分,又可分為兩個部分:
邏輯部分,除了config對象之外的部分,對應於原生的.js文件
配置部分,即config對象,對應於原生的.json文件
-
結構
<template>部分,對應於原生的.wxml文件 -
樣式
<style>部分,對應於原生的.wxss文件
①components組件:
import wepy from 'wepy'; export default class MyComponent extends wepy.component { props = {}//接收父組件傳來的參數 customData = {} // 自定義數據 customFunction () {} //自定義方法 onLoad () {} // 在Page和Component共用的生命周期函數 data = {}; // 頁面所需數據均需在這里聲明,可用於模板數據綁定 components = {}; // 聲明頁面中所引用的組件,或聲明組件中所引用的子組件 mixins = []; // 聲明頁面所引用的Mixin實例 computed = {}; // 聲明計算屬性(詳見后文介紹) watch = {}; // 聲明數據watcher(詳見后文介紹) methods = {}; // 聲明頁面wxml中標簽的事件處理函數。注意,此處只用於聲明頁面wxml中標簽的bind、catch事件,自定義方法需以自定義方法的方式聲明 events = {}; // WePY組件事件處理函數對象,存放響應組件之間通過$broadcast、$emit、$invoke所傳遞的事件的函數 } /** 與page不同的是component不存在: onShow () {} // 只在Page中存在的頁面生命周期函數 config = {}; // 只在Page實例中存在的配置數據,對應於原生的page.json文件,類似於app.wpy中的config onReady() {} // 只在Page中存在的頁面生命周期函數 **/
**無法實現組件化的松耦合與復用
(如,模板A中綁定一個bindtap="myclick",模板B中同樣綁定一樣bindtap="myclick",那么就會影響同一個頁面事件、數據)
a、引用組件
//引入組件文件 import Child from '../components/child'; export default class Index extends wepy.component { //聲明組件,分配組件id為child,需要注意的是,WePY中的組件都是靜態組件,是以組件ID作為唯一標識的,
每一個ID都對應一個組件實例,當頁面引入兩個相同ID的組件時,這兩個組件共用同一個實例與數據,當其中一個組件數據變化時,另外一個也會一起變化。 components = { //為兩個相同組件的不同實例分配不同的組件ID,從而避免數據同步變化的問題 child: Child, }; }
//在html中使用組件
<child></child>
②頁面page.wpy
Page頁面實際上繼承自Component組件,即Page也是組件。
除擴展了頁面所特有的config配置以及特有的頁面生命周期函數之外,其它屬性和方法與Component一致:
import wepy from 'wepy'; export default class MyPage extends wepy.page { customData = {} // 自定義數據 customFunction () {} //自定義方法 onLoad () {} // 在Page和Component共用的生命周期函數 onUnload() {} // 監聽頁面卸載 onReady() {} // 只在Page中存在的頁面生命周期函數 onShow () {} // 只在Page中存在的頁面生命周期函數,當小程序啟動,或從后台進入前台顯示 onHide() {} // 只在Page中存在的頁面生命周期函數,當小程序從前台進入后台 config = {}; // 只在Page實例中存在的配置數據,對應於原生的page.json文件,類似於app.wpy中的config data = {}; // 頁面所需數據均需在這里聲明,可用於模板數據綁定 components = {}; // 聲明頁面中所引用的組件,或聲明組件中所引用的子組件 mixins = []; // 聲明頁面所引用的Mixin實例 computed = {}; // 聲明計算屬性 watch = {}; // 聲明數據watcher methods = {}; // 聲明頁面wxml中標簽的事件處理函數。注意,此處只用於聲明頁面wxml中標簽的bind、catch事件,自定義方法需以自定義方法的方式聲明 events = {}; // WePY組件事件處理函數對象,存放響應組件之間通過$broadcast、$emit、$invoke所傳遞的事件的函數 onPullDownRefresh(){} // 監聽用戶下拉動作 onReachBottom(){} // 頁面上拉觸底事件的處理函數 onShareAppMessage(){} // 用戶點擊右上角分享 onPageScroll(){} // 頁面滾動 onTabItemTap(){} // 當前是 tab 頁時,點擊 tab 時觸發 }
③狀態管理store(redux)
④app.wpy:小程序入口
繼承自wepy.app類;包含config配置對象、globalData對象、自定方法屬性、小程序生命周期函數;
在page頁面中可以使用this.$parent調用實例
<script> import wepy from 'wepy'; export default class extends wepy.app { config = { pages:[// pages定義當前小程序所有頁面路徑,讓微信客戶端知道當前你的小程序頁面定義在哪個目錄 'pages/index', 'pages/mine' ], window:{//window定義小程序所有頁面的頂部背景顏色,文字顏色定義等。 "backgroundTextStyle": "light", "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "頂部標題", "navigationBarTextStyle": "black" }, tabBar: { selectedColor: '#ea9100',//底部導航字體選中時的顏色 list: [ { pagePath: 'pages/index',//導航頁面路徑(必須在pages中定義) text: '首頁',//導航名 iconPath: 'img/index.png',//未選中的導航icon selectedIconPath: 'img/index1.png'//選中時的導航icon }, { pagePath: 'pages/mine', text: '我的', iconPath: 'img/mine.png', selectedIconPath: 'img/mine1.png' } ] }, }; onLaunch() {//初始化 console.log(this); } onShow(){}//當小程序啟動,或從后台進入前台顯示 onHide(){}//當小程序從前台進入后台 } </script> <style lang="less"> /** less **/ </style>
