微信小程序wepy框架详解(一)
wepy——微信小程序的一种框架
简述
由于项目原因,我于两个多月前转到微信端用wepy进行开发。
wepy开发风格接近于 Vue.js,支持组件 Props 传值,自定义事件、组件分布式复用Mixin、Redux、计算属性函数computed、模板内容分发slot等等,支持ES6/7部分语法以及less/sass等样式语言。
wepy官方文档地址:wepy官方文档
wepy的基本用法我就不再赘述,请自行看官方文档。
值得一提的是初学者记得在微信开发者工具的项目设置中如下配置,否则很可能项目报错无法运行
一、生命周期
应用的生命周期
属性 | 描述 | 如何触发 |
---|---|---|
onLaunch | 监听小程序初始化 | 当小程序初始化完成后触发,可理解为清空后台运行程序后打开小程序时触发 |
onShow | 监听小程序显示 | 当小程序初始化后,或从后台切换到前台后触发(后台切换到前台后面会详细说明) |
onHide | 监听小程序隐藏 | 当小程序从前台切换到后台时(前台切换到后台后面会详细说明) |
正常触发顺序
1 onLaunch: 用户打开小程序
2 onShow:初始化结束或用户曾在后台运行小程序,现在又打开了小程序
3 onHide:用户切换到其他应用(小程序在后台运行)
页面的生命周期
属性 | 描述 | 如何触发 |
---|---|---|
onLoad | 监听页面加载 | 当某页面首次加载时触发,每个页面只触发一次 |
onReady | 监听页面初次渲染完成 | 当页面加载并渲染完成后触发,每个页面触发一次 |
onShow | 监听页面显示 | 一般在onLoad执行后执行,可以执行多次,当前页面一旦显示便会执行 |
onHide | 监听页面隐藏 | 当小程序变为后台运行或跳转到其他页面时触发 |
onUnload | 监听页面卸载 | 当小程序从前台切换到后台时(前台切换到后台后面会详细说明) |
正常触发顺序
1 onLoad: 用户初次打开某页面,每个页面只触发一次
2 onShow:页面一旦显示即触发,包括用户来回切换页面
3 onReady:页面初次渲染完成,每个页面只触发一次
4 onHide:小程序被切换到后台运行或者用户切换到其他页面
5 onUnload: 当使用重定向方法wx.redirectTo(OBJECT)或关闭当前页返回上一页wx.navigateBack(),触发onUnload。
二、事件传值
Template:
<text alt="添加" class="plus-icon" id="plus" @tap="goodsChange({{ item }}, {{'add'}})" >Plus</text>
JavaScript:
goodsChange(data, status) { // doSomething }
- 注意 事件函数要写在methods里
三、Watcher监听器
example:
watch = { someName(newValue, oldValue) { // doSomething } }
- someName为被监听的某数据
- newValue为新值,oldValue为旧值
- someName一旦变化即触发该函数
- 监听函数需要写在watch属性里
四、组件通信方法
组件有三种通信方法
- $broadcast:由父组件发起,所有子组件都会收到此广播事件,除非事件被手动取消。
如果Page_Index组件发起一个$broadcast事件,那么按先后顺序采用广度优先遍历依次接收到该事件的组件为:
ComA、ComB、ComC、ComD、ComE、ComF、ComG、ComH - $emit:与$broadcast正好相反,事件是向上传递的。
事件发起组件的所有祖先组件会依次接收到$emit事件。
如下图所示,如果组件ComE发起一个$emit事件,那么接收到事件的先后顺序为:组件ComA、页面Page_Index。 $invoke:是一个页面或组件对另一个组件中的方法的直接调用。
通过传入组件相对路径找到相应的组件,然后再调用其方法。比如Page_Index组件中想要调用ComA组件中的一个名为someMethod方法的事件
this.$invoke('ComA', 'someMethodInComA', 'someArguments');
再比如再组件ComA中调用组件ComG的某个方法
this.$invoke('./../ComB/ComG', 'someMethodInComG', 'someArguments')
- 注意路径为相对路径
- $broadcast:由父组件发起,所有子组件都会收到此广播事件,除非事件被手动取消。
组件有两种通信方式
默认通信方式
- exapmle using $emit:
super
// events对象中所声明的函数为用于监听组件之间的通信与交互事件的事件处理函数 events = { 'some-event': (p1, p2, p3, p4, $event) => { console.log($event) // 打出触发some-event的事件对象 console.log(p1, p2, p3, p4) } };
sub
methods = { selectType(data) { // 子组件中的某点击事件 this.$emit('some-event', 1, 2, 3, 4) // 向父组件的some-event监听事件发送参数 } };
自定义通信方式(1.48版本新增方式,注意兼容问题)
example:
@customEvent.user="myFn"
- @表示时间修饰符
- customEvent表示事件名称
.user表示事件后缀,共有三种
@tap.default: 绑定小程序冒泡型事件,.default后缀可省略不写
可以理解为普通的原生冒泡机制
example:<view @tap.default="wrapperView"> <view @tap.default="middleView"> <view @tap.default="centerView"> this is a Concentric circle </view> </view> </view>
methods = { centerView(data) { console.log('center-view has benn taped') }, middleView() { console.log('middle-view has been taped') }, wrapperView() { console.log('wrapper-view has been taped') } };
输出是这样的
@tap.stop:绑定小程序捕获型事件
可以理解为原生js的阻止冒泡机制e.stopPropagation()/e.cancelBubble = true
example:<view @tap.default="wrapperView"> <view @tap.stop="middleView"> <view @tap.default="centerView"> this is a Concentric circle </view> </view> </view>
methods = { centerView(data) { console.log('center-view has benn taped') }, middleView() { console.log('middle-view has been taped') }, wrapperView() { console.log('wrapper-view has been taped') } };
输出是这样的
可以理解为tap.stop是在tap.default函数末尾添加了以下代码e.stopPropagation() // w3c规定的阻止冒泡机制 e.cancelBubble = true // ie的阻止冒泡机制
@eventName.user:绑定用户自定义组件事件,通过$emit触发。
注意,如果用了自定义事件,则events中对应的监听函数不会再执行。
example:In parentNode
<!--分类侧边栏--> <SideTab @change.user="selectTypeInParentNode" />
methods = { selectTypeInParentNode(data) { console.log('in methods') console.log(data) // do something } } events = { 'change': (data) => { console.log('in events') console.log(data) } }
In childNode
<view @tap="selectTypeInChildNode({{ item }})"></view>
methods = { selectTypeInChildNode(data) { this.$emit('change', data) // 会调用父组件中的<SideTab />组件的@change属性所指的事件函数 // 而非调用父组件events里面的监听事件 } }
- 自定义方式输出
两种方式的区别
默认冒泡方式
in parentNode
<Child />
events = { 'change': (data) => { console.log('in events') console.log(data) } }
in childNode
<view @tap="selectType({{ item }})"></view>
selectType(data) { console.log('center-view has benn taped') this.$emit('change', data) },
- printf
自定义方式可以看上面详细说明
- printf
五、组件化和Props传值
- 此处以动态传值为例
父组件中
<repeat for="{{tradeList}}" key="index" index="index" item="item"> <GoodsItem :parentToChildData.sync="item" @parentToChildFunction.user="goodsSelectChange"></GoodsItem> </repeat>
methods = { async goodsSelectChange(data, status) { // 传递给子组件的函数 // doSomething },
子组件中
<text alt="添加" class="plus-icon" id="plus" @tap="goodsChange({{ item }}, {{'add'}})" >+</text>
props = { // 接收父组件传递下来的数据 parentToChildData: {} }; methods = { goodsChange(data, status) { this.$emit('parentToChildFunction', data, status) // $emit为向上传值,具体可参考官方文档的组件传值 // 给父组件的parentToChildFunction属性的函数(goodsSelectChange)传递参数(data,status) } };
本文参考
- WePY 让小程序支持组件化开发的框架
- WePY 生命周期
- 基于微信小程序的在线商城
谢谢
本文章内容有任何问题请留言提问,若有错误欢迎纠正 本人邮箱 [email protected]