转载:https://www.jianshu.com/p/93d5a4b99777
安装 wepy 命令行工具。
npm install wepy-cli -g
在开发目录生成开发DEMO。
wepy new myproject
开发实时编译。
wepy build --watch
项目目录结构
dist
node_modules
src
components
com_a.wpy
com_b.wpy
pages
index.wpy
page2.wpy
app.wpy
package.json
使用微信开发者工具新建项目,本地开发选择dist目录。
微信开发者工具 --> 项目 --> 关闭ES6转ES5。
本地项目根目录运行wepy build --watch,开启实时编译。
官方DEMO代码:
//index.js //获取应用实例 var app = getApp() Page({ data: { motto: 'Hello World', userInfo: {} }, //事件处理函数 bindViewTap: function() { console.log('button clicked') }, onLoad: function () { console.log('onLoad') } })
基于wepy的实现:
import wepy from 'wepy'; export default class Index extends wepy.page { data = { motto: 'Hello World', userInfo: {} }; methods = { bindViewTap () { console.log('button clicked'); } }; onLoad() { console.log('onLoad'); }; }
wepy支持组件化开发
组件示例代码:
// index.wpy <template> <view> <component id="pannel" path="pannel"></component> <component id="counter1" path="counter"></component> <component id="counter2" path="counter"></component> <component id="list" path="list"></component> </view> </template> <script> import wepy from 'wepy'; import List from '../components/list'; import Panel from '../components/panel'; import Counter from '../components/counter'; export default class Index extends wepy.page { config = { "navigationBarTitleText": "test" }; components = { panel: Panel, counter1: Counter, counter2: Counter, list: List }; } </script>
官方DEMO:
project
pages
index
index.json
index.js
index.wxml
index.wxss
log
log.json
log.wxml
log.js
log.wxss
app.js
app.json
app.wxss
使用wepy框架后目录结构:
project
src
pages
index.wpy
log.wpy
app.wpy
wepy默认使用babel编译,支持ES6 / 7的一些新特性
示例代码:
import wepy from 'wepy'; export default class Index extends wepy.page { getData() { return new Promise((resolve, reject) => { setTimeout(() => { resolve({data: 123}); }, 3000); }); }; async onLoad() { let data = await this.getData(); console.log(data.data); }; }
原有代码:
onLoad = function () { var self = this; wx.login({ success: function (data) { wx.getUserInfo({ success: function (userinfo) { self.setData({userInfo: userinfo}); } }); } }); }
基于wepy实现代码:
async onLoad() { await wx.login(); this.userInfo = await wx.getUserInfo(); }
执行wepy new demo后,会生成类似配置文件。
{ "wpyExt": ".wpy", "sass": {}, "less": {}, "babel": {} } <style type="less" src="page1.less"></style> <template type="wxml" src="page1.wxml"></template> <script> // some code </script>
程序入口app.wpy
<style type="less"> /** less **/ </style> <script> import wepy from 'wepy'; export default class extends wepy.app { config = { "pages":[ "pages/index/index" ], "window":{ "backgroundTextStyle": "light", "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "WeChat", "navigationBarTextStyle": "black" } }; onLaunch() { console.log(this); } } </script>
wepy页面index.wpy
<style type="less"> /** less **/ </style> <template type="wxml"> <view> </view> <component id="counter1" path="counter"></component> </template> <script> import wepy form 'wepy'; import Counter from '../components/counter'; export default class Index extends wepy.page { config = {}; components = {counter1: Counter}; data = {}; methods = {}; events = {}; onLoad() {}; // Other properties } </script>
wepy组件com.wpy
<style type="less"> /** less **/ </style> <template type="wxml"> <view> </view> </template> <script> import wepy form 'wepy'; export default class Com extends wepy.component { components = {}; data = {}; methods = {}; events = {}; // Other properties } </script>
wepy 组件通信与交互
wepy.component基类提供三个方法$broadcast,$emit,$invoke $this.$emit('some-event', 1, 2, 3, 4); 组件的事件监听需要写在events属性下,如: import wepy form 'wepy'; export default class Com extends wepy.component { components = {}; data = {}; methods = {}; events = { 'some-event': ($event, ...args) { console.log(`${this.name} receive ${$event.name} from ${$event.source.name}`); } }; // Other properties }
$invoke$invoke是一个组件对另一个组件的直接调用,通过传入的组件路径找到相应组件,然后再调用其方法。 如果想在Page_Index中调用组件A的某个方法: this.$invoke('ComA', 'someMethod', 'someArgs'); 如果想在组件A中调用组件G的某个方法: this.$invoke('./../ComB/ComG', 'someMethod', 'someArgs');
小程序通过Page提供的setData方法去绑定数据,如:
this.setData({title: 'this is title'});
wepy数据绑定方式
this.title = 'this is title';
在函数运行周期之外的函数里去修改数据需要手动调用$apply方法。如:
setTimeout(() => { this.title = 'this is title'; this.$apply(); }, 3000);
// 官方
wx.request({ url: 'xxx', success: function (data) { console.log(data); } });
// wepy 使用方式
// request 接口从只接收Object变为可接收String
wx.request('xxxx').then((d) => console.log(d));
优化事件参数传递
// 官方 <view id="tapTest" data-hi="WeChat" bindtap="tapName"> Click me! </view> Page({ tapName: function(event) { console.log(event.currentTarget.hi)// output: WeChat } }); // wepy 建议传参方式 <view id="tapTest" data-wepy-params="1-wepy-something" bindtap="tapName"> Click me! </view> events: { tapName (event, id, title, other) { console.log(id, title, other)// output: 1, wepy, something } }
改变数据绑定方式
// 官方 <view> {{ message }} </view> onLoad: function () { this.setData({message: 'hello world'}); } // wepy <view> {{ message }} </view> onLoad () { this.message = 'hello world'; }
组件代替模板和模块
// 官方 <!-- item.wxml --> <template name="item"> <text>{{text}}</text> </template> <!-- index.wxml --> <import src="item.wxml"/> <template is="item" data="{{text: 'forbar'}}"/> <!-- index.js --> var item = require('item.js') // wepy <!-- /components/item.wpy --> <text>{{text}}</text> <!-- index.wpy --> <template> <component id="item"></component> </template> <script> import wepy from 'wepy'; import Item from '../components/item'; export default class Index extends wepy.page { components = { Item } } </script>
WePY Demo
<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>
登录相关API wx.login。
获取用户信息API wx.getUserInfo。
Storage相关 wx.getStorage,wx.setStorage,wx.clearStorage。
开发
目录结构: src components alpha.wpy --- 联系人 chatboard.wpy --- "聊天面板" 组件 contact.wpy --- "联系人" 组件 discovery.wpy --- "发现" 组件 input.wpy --- 聊天页输入框组件 list.wpy --- 菜单列表组件 me.wpy --- "我" 组件 message.wpy --- message 组件 tab.wpy --- tab 组件 pages chat.wpy --- 聊天页 index.wpy --- 首页 app.wpy --- 小程序入口
src/pages/index.wpy: <style type="sass"> .body, .tab_item { height: 100%; } </style> <template> <view class="body"> <view class="tab_item tab_message"> <component id="message"></component> </view> <view class="tab_item tab_contact"> <component id="contact"></component> </view> <view class="tab_item tab_discovery"> <component id="discovery"></component> </view> <view class="tab_item tab_me"> <component id="me"></component> </view> <component id="tab"></component> </view> </template> src/pages/chat.wpy: <style type="sass"> .body { height: 100%; background-color: #ededed; } </style> <template> <view class="body"> <component id="chartboard"></component> <component id="input"></component> </view> </template>
import m_contacts from '../mocks/contact'; import m_history from '../mocks/history'; export default { // 拉取用户信息 getUserInfo () {}, // 拉取与某个用户的聊天历史记录 getHistory (id) {}, // 拉取首页聊天列表 getMessageList () {}, // 发送聊天信息 sendMsg (to, msg, type = 'text') {} }
<template> <view class="message"> <block wx:for="{{list}}" wx:for-index="index" wx:for-item="item"> <view class="item" bindtap="select" data-wepy-params="{{item.id}}"> <view class="header"> <image class="img" src="{{item.icon}}"></image> </view> <view class="content"> <view class="name">{{item.name}}</view> <view class="lastmsg">{{item.lastmsg}}</view> </view> </view> </block> </view> </template> <script> import wepy from 'wepy'; import api from '../common/api'; export default class Message extends wepy.component { data = { list: [] }; methods = { select (evt, id) { wx.navigateTo({url: 'chat?id=' + id}); } }; async loadMessage () { this.list = await api.getMessageList(); this.$apply(); } } </script>
// src/pages/index.wpy onShow() { this.$invoke('message', 'loadMessage'); }
src/pages/index: <template> <view class="body"> <view class="tab_item tab_message" hidden="{{currentTab != 0}}"> <component id="message"></component> </view> <view class="tab_item tab_contact" hidden="{{currentTab != 1}}"> <component id="contact"></component> </view> <view class="tab_item tab_discovery" hidden="{{currentTab != 2}}"> <component id="discovery"></component> </view> <view class="tab_item tab_me" hidden="{{currentTab != 3}}"> <component id="me"></component> </view> <component id="tab"></component> </view> </template> <script> //.... changeTab (idx) { this.currentTab = +idx; this.$apply(); } </script>
<script> import wepy from 'wepy'; export default class Tab extends wepy.component { data = { active: 0, }; methods = { change (evt, idx) { this.active = +idx; this.$parent.changeTab(idx); } }; } </script>
parent.wpy <child :item.sync="myitem" /> <repeat for="{{list}}" item="item" index="index"> <item :item="item" /> </repeat>