数据绑定
与vue一致
事件绑定及传参
<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}}
页面的跳转
页面的跳转需要先在app.wpy的config中的pages中设置页面的路由,在页面中通过navigateTo跳转到相应页面。
在wepy.page的脚本中可以通过this.$navigate({url:""})实现页面的跳转。
而在wepy.component的组件中可以通过this. p a r e n t . parent. 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
<child :title = 'parentTitle' :syncTitle.sync = 'parentTitle' :twoWayTitle = 'parentTitle'></child>
在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
<template>
<view>
<children @childFun.user = 'someEvent'></children>
</view>
</template>
<script>
export default class Parent extends wepy.page{
data = {
name: 'parent'
}
events = {
'some-event': (p1, p2, p3, $event) => {
// 输出为'parent receive some-event children',$event.source指向子组件。
console.log(`${this.name} receive ${$event.name} from ${$event.source.name}`)
}
}
onLoad () {
this.$broadcast('getIndex', 1, 4)
}
methods = {
someEvent (...p) {
// 输出[1, 2, 3, _class]。
console.log(p)
}
}
}
</script>
children.wpy
<script>
export default class Parent extends wepy.page{
data = {
name: 'children'
}
onLoad () {
// this.$emit('some-event', 1, 2, 3)
// 触发组件中的自定义事件
this.$emit('childFun', 1, 2, 3)
}
events = {
'getIndex': (...p) => {
console.log(p) // 输出[1, 4]
}
}
}
在父组件中给子组件添加属性@childFun.user = 'someEvent’后,在子组件中修改触发条件this.$emit(‘childFun’, 1, 2, 3)
//$invoke
父组件向子组件发送事件:
使用import导入子组件后,在使用时可以直接通过
this.
i
n
v
o
k
e
(
′
子
组
件
,
必
须
要
单
引
号
括
起
来
′
,
′
子
组
件
方
法
名
称
′
,
p
a
r
a
m
1
,
p
a
r
a
m
2
,
p
a
r
a
m
3.......
)
;
子
组
件
间
发
送
事
件
:
t
h
i
s
.
invoke('子组件,必须要单引号括起来', '子组件方法名称', param1,param2,param3.......); 子组件间发送事件: this.
invoke(′子组件,必须要单引号括起来′,′子组件方法名称′,param1,param2,param3.......);子组件间发送事件:this.invoke(‘子组件的相对路径’, ‘子组件方法名称’, param1,param2,param3…);
子组件的相对路径的理解: 当设置’./‘即当前组件,’…/'为父组件,以此类推。它可以指定向哪一个组件分发内容,但只适用于简单的组件树结构,复杂的结构考虑使用redux。
在子组件中使用broadcast会触发子组件及子孙组件中的相同事件。其中broadcast触发的事件设置在组件中的events中,而invoke中的第一个参数可以直接设置为components中的值,当设置相对路径时,即根据当前组件在整个组件树中的位置来确定路径,它可以指定向特定的组件传值,但当结构复杂时,需要嵌套的路径会比较复杂,不好维护,考虑用redux实现。
动态设置title
#可以在onload中使用原生代码
onLoad(){
wx.setNavigationBarTitle({
title: '当前页面'
})
}
设置全局样式
//app.wpy
page{
min-height: 100%;
background: #F1F4FD;
font-size: 25rpx;
}
获取全局变量
#组件内
wepy.$instance.globalData
#页面内
this.$parent.globalData
全局变量
我的用法是:
单独写一个 global-data.js
// global-data.js
const foo = 'I love hashimoto ai';
export default {
foo
}
在用到的 page 里的 <script> 标签开头部分
// pages/ohMyLove/index.wpy
...
<script>
import wepy from 'wepy';
const { foo } = require('../js-utils/global-data').default;
...
这样就可以尽情使用 foo 了
$apply
重新渲染数据
调完接口数据没有刷新,就是这个原因造成的
this.$apply();
小程序处理json
JSON.parse()
组件中设置标题
onLoad(){
wx.setNavigationBarTitle({
title: '需求列表'
})
};