wepy文档:https://tencent.github.io/wepy/
全局安装wepy: npm i -g wepy-cli
初始化项目: wepy init standard myproject
切换到项目目录: cd myproject
安装依赖: npm install
wepy目录:
├── dist // 打包后的文件
├── src // 开发文件目录
│ ├── components // 组件目录
│ ├── images // 图片文件目录
│ ├── mixins // 通用函数
│ ├── mocks // 模拟数据目录
│ ├── pages // 小程序单个页面目录
│ ├── store // redux存储数据(页面传值)
│ ├── app.wpy // 入口文件(配置页面的跳转)
│ ├── index.html // 模版文件
├── wepy.config.js // 配置文件
重要提醒
- 使用微信开发者工具-->添加项目,项目目录请选择dist目录。
- 微信开发者工具-->项目-->关闭ES6转ES5。 重要:漏掉此项会运行报错。
- 微信开发者工具-->项目-->关闭上传代码时样式自动补全。 重要:某些情况下漏掉此项也会运行报错。
- 微信开发者工具-->项目-->关闭代码压缩上传。 重要:开启后,会导致真机computed, props.sync 等等属性失效。(注:压缩功能可使用WePY提供的build指令代替,详见后文相关介绍以及Demo项目根目录中的wepy.config.js和package.json文件。)
- 本地项目根目录运行npm run dev(wepy build --watch),开启实时编译。(注:如果同时在微信开发者工具-->设置-->编辑器中勾选了文件保存时自动编译小程序,将可以实时预览,非常方便。)
开发
index.template.html: 为模块文件
其中通过
wepy.app
创建入口文件,wepy.page
创建页面文件,wepy.component
创建组件文件。
app.wpy:入口文件,包含config,globalData,constructor和生命周期。在config中配置路由
- config:配置pages,window,tabBar。分别为页面路由配置,页面导航栏配置,页面底部栏配置。详细配置在小程序框架配置
- globalData: 全局参数配置,用于多个页面的公用参数。
- constructor: 拦截器的配置。
- 生命周期使用
其中如果在页面开发中需要用到async/await的话,需要在app.wpy中使用import 'wepy-async-function'加载模块,不然在编译后页面会报错,导致async/await无法使用。
// 设置路由,导航栏,底部栏
config = {
pages: [
'pages/main',
'pages/admin-center'
],
window: {
backgroundTextStyle: 'light',
navigationBarBackgroundColor: '#fff',
navigationBarTitleText: 'WeChat',
navigationBarTextStyle: 'black'
},
tabBar = {
color: '#AEADAD',
selectedColor: '#049BFF',
backgroundColor: '#fff',
borderStyle: 'black',
list: [{
pagePath: 'pages/index',
text: '首页',
"iconPath": "images/ico-home.png",
"selectedIconPath": "images/ico-home-d.png"
}, {
pagePath: 'pages/admin-center',
text: '借阅',
"iconPath": "images/ico-setting.png",
"selectedIconPath": "images/ico-setting-d.png"
}]
}
}
// 全局参数(方便后期各页面中的使用)
globalData = {
prizeList: [], // 领取的奖品列表
}
// 设置拦截器,intercept为拦截器函数
constructor () {
super()
intercept(this)
}
// 页面加载
onLaunch(res) {
console.log(res)
}
wpy模块中的属性
export default class Index @extends wepy.page{
customData = {} // 自定义数据
customFunction () {} //自定义方法
onLoad () {} // 在Page和Component共用的生命周期函数
onShow () {} // 只在Page中存在的页面生命周期函数
config = {}; // 只在Page实例中存在的配置数据,对应于原生的page.json文件
data = {}; // 页面所需数据均需在这里声明,可用于模板数据绑定
components = {}; // 声明页面中所引用的组件,或声明组件中所引用的子组件
mixins = []; // 声明页面所引用的Mixin实例
computed = {}; // 声明计算属性(详见后文介绍)
watch = {}; // 声明数据watcher(详见后文介绍)
methods = {}; // 声明页面wxml中标签的事件处理函数。注意,此处只用于声明页面wxml中标签的bind、catch事件,自定义方法需以自定义方法的方式声明
events = {}; // 声明组件之间的事件处理函数
}
属性 | 说明 |
---|---|
config | 页面配置对象,对应于原生的page.json文件,类似于app.wpy中的config |
components | 页面组件列表对象,声明页面所引入的组件列表 |
data | 页面渲染数据对象,存放可用于页面模板绑定的渲染数据 |
methods | wxml事件处理函数对象,存放响应wxml中所捕获到的事件的函数,如bindtap、bindchange,不能用于声明自定义方法。 |
events | WePY组件事件处理函数对象,存放响应组件之间通过emit、$invoke所传递的事件的函数 |
其它 | 小程序页面生命周期函数,如onLoad、onReady等,以及其它自定义的方法与属性 |
wpy中自定义的函数应当写在与methods平级的位置,不用写在methods中。
页面的跳转
页面的跳转需要先在app.wpy
的config
中的pages
中设置页面的路由,在页面中通过navigateTo跳转到相应页面。在wepy.page的脚本中可以通过this.$navigate({url:""})
实现页面的跳转。而在wepy.component的组件中可以通过this.$parent.$navigate({url:""})
或wepy.navigateTo
实现。
wepy.navigateTo({
url: '/pages/info'
})
wepy中的生命周期
wepy中的生命周期的钩子函数有:onLoad,onReady,onShow,onPrefetch等,其中onReady,onShow,onPrefetch
只有wepy.page中才有用。wepy.component只支持onLoad,其他都不会触发。
- onLoad: 页面加载完成时调用,一个页面只会调用一次。(在路由跳转的时候通过
navigateTo
跳转的话onload
会重新执行,通过navigateBack
跳转的话onLoad
不会重新执行) - onShow:页面显示的时候调用。
- onReady: 页面中的所有资源加载完成时调用。
- onPrefetch:在页面跳转时触发,用于预加载和预查询数据。
- onUnload: 在页面卸载时触发(通过redirectTo,switchTab,navigateBack,reLaunch会触发当前页面中的onUnload,但navigateTo不会触发)。
生命周期顺序:onPrefetch > onLoad > onShow > onReady。
onPrefetch
这个生命周期是wepy中扩展的,它的触发需要通过this.$navigate
及其他wepy封装的跳转方式才能实现。当设置onPrefetch
后,可以在onLoad
中设置变量来获取onPrefetch
中返回的值。
案例:
onLoad (params, data) {
data.prefetch.then((list) => {
this.adminMath = list.chasucccnt.data.succcnt
this.recordInfo = list.adminCenter.data.challengeRecList
this.heightScore = list.adminCenter.data.hs
this.hadMath = list.adminCenter.data.cc
this.$apply()
})
}
// chasucccnt,getAdminCenter为请求后台的函数,返回的数据结构是{data:{succcnt:0}。
async onPrefetch () {
let chasucccnt = await this.chasucccnt()
let adminCenter = await this.getAdminCenter()
return new Promise((resolve, reject) => {
resolve({
chasucccnt: chasucccnt,
adminCenter: adminCenter
})
})
}
props实现父子组件之间的传值
官方案例:
// parent.wpy
在script中的设置
data = {
parentTitle: 'p-title'
}
// child.wpy
props = {
// 静态传值
title: String,
// 父向子单向动态传值
syncTitle: {
type: String,
default: 'null'
},
twoWayTitle: {
type: Number,
default: 'nothing',
twoWay: true
}
};
onLoad () {
console.log(this.title); // p-title
console.log(this.syncTitle); // p-title
console.log(this.twoWayTitle); // p-title
this.title = 'c-title';
console.log(this.$parent.parentTitle); // p-title.
this.twoWayTitle = 'two-way-title';
this.$apply();
console.log(this.$parent.parentTitle); // two-way-title. --- twoWay为true时,子组件props中的属性值改变时,会同时改变父组件对应的值
this.$parent.parentTitle = 'p-title-changed';
this.$parent.$apply();
console.log(this.title); // 'c-title';
console.log(this.syncTitle); // 'p-title-changed' --- 有.sync修饰符的props属性值,当在父组件中改变时,会同时改变子组件对应的值。
}
有上案例可以知道
:title
为静态传值,即只有第一次有效,后面改变值后子组件中的title不会发生改变,当在属性后添加.sync后,即该属性发生改变会导致子组件中相应的值发生改变,当在子组件中的props
中设置twoWay: true
后,可以实现父子组件的双向绑定。
组件之间的数据通信
wepy中的通信主要采用三种方法:emit, $invoke;
- $broadcast:父组件触发所有子组件(包含子孙级组件)事件。
- emit可以用于触发自定义事件而events中声明的函数将不会再执行。(与vue中的用法不同,vue中需要在父组件中设置子组件的属性,用于在子组件中触发。而wepy中则不需要,只要在events中设置方法就可以在子组件中触发。)
- $invoke:页面或子组件触发另一个子组件事件。
parent.wpy
children.wpy