import wepy from 'wepy'; // 声明一个App小程序实例 export default class MyAPP extends wepy.app { } // 声明一个Page页面实例 export default class IndexPage extends wepy.page { } // 声明一个Component组件实例 export default class MyComponent extends wepy.component { }
this.$parent
来访问App实例。config
配置以及特有的页面生命周期函数以外,其它属性和方法与Component一致。组件小程序
<template> <view class="child1"> <child></child> </view> <view class="child2"> <anotherchild></anotherchild> </view> </template> <script> import wepy from 'wepy'; import Child from '../components/child'; export default class Index extends wepy.page { components = { //为两个相同组件的不一样实例分配不一样的组件ID,从而避免数据同步变化的问题 child: Child, anotherchild: Child }; } </script>
childCom
转换成child-com
),与Vue中的习惯不一样。
计算属性:promise
data = { a: 1 } // 计算属性aPlus,在脚本中可经过this.aPlus来引用,在模板中可经过{{ aPlus }}来插值 computed = { aPlus () { return this.a + 1 } }
props传值:app
父子组件之间传值的一种机制,包括静态传值与动态传值。异步
1.静态传值模块化
静态传值为父组件向子组件传递常量数据,所以只能传递String字符串类型。函数
2.动态传值组件化
动态传值是指父组件向子组件传递动态数据内容,父子组件数据彻底独立互不干扰。但能够经过使用.sync
修饰符来达到父组件数据绑定至子组件的效果,也能够经过设置子组件props的twoWay: true
来达到子组件数据绑定至父组件的效果。那若是既使用.sync
修饰符,同时子组件props
中添加的twoWay: true
时,就能够实现数据的双向绑定了。this
twoWay
为true
时,表示子组件向父组件单向动态传值,而twoWay
为false
(默认值,可不写)时,则表示子组件不向父组件传值。这是与Vue不一致的地方。//parent.wpyspa
<child :title="parentTitle" :syncTitle.sync="parentTitle" :twoWayTitle="parentTitle"></child> data = { parentTitle: 'p-title' };
// child.wpy双向绑定
props = { // 静态传值 title: String, // 父向子单向动态传值 syncTitle: { type: String, default: 'null' }, twoWayTitle: { type: String, 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属性值,当在父组件中改变时,会同时改变子组件对应的值。 }
组件通讯与交互
wepy.component
基类提供$broadcast
、$emit
、$invoke
三个方法用于组件之间的通讯和交互。
this.$emit('some-event', 1, 2, 3, 4);
用于监听组件之间的通讯与交互事件的事件处理函数须要写在组件和页面的events
对象中:
import wepy from 'wepy' export default class Com extends wepy.component { components = {}; data = {}; methods = {}; // events对象中所声明的函数为用于监听组件之间的通讯与交互事件的事件处理函数 events = { 'some-event': (p1, p2, p3, $event) => { console.log(`${this.$name} receive ${$event.name} from ${$event.source.$name}`); } }; // Other properties }
$broadcast
$broadcast
事件是由父组件发起,全部子组件都会收到此广播事件,除非事件被手动取消。事件广播的顺序为广度优先搜索顺序。若是页面Page_Index
发起一个$broadcast
事件,那么按前后顺序依次接收到该事件的组件为:ComA、ComB、ComC、ComD、ComE、ComF、ComG、ComH。以下图:
$emit
$emit
与$broadcast
正好相反,事件发起组件的全部祖先组件会依次接收到$emit
事件。若是组件ComE发起一个$emit
事件,那么接收到事件的前后顺序为:组件ComA、页面Page_Index。以下图:
$invoke
$invoke
是一个页面或组件对另外一个组件中的方法的直接调用,经过传入组件路径找到相应的组件,而后再调用其方法。
好比,想在页面Page_Index
中调用组件ComA的某个方法:(该事件只传给ComA,而不是广播)
this.$invoke('ComA', 'someMethod', 'someArgs');
若是想在组件ComA中调用组件ComG的某个方法:(不存在父子关系的两个组件)
this.$invoke('./../ComB/ComG', 'someMethod', 'someArgs');
$apply : 组件发起脏检查。
正常流程下,改变数据后,组件会在流程结束时自动触发脏检查。 在异步或者回调流程中改变数据时,须要手动调用$apply
方法。
this.userName = 'Gcaufy'; this.$apply();
$nextTick: 组件数据绑定完成后的回调事件。在不传入function时,返回一个promise对象。
this.userName = 'Gcaufy'; this.$nextTick(function () { console.log('UI updated'); });
this.userName = 'Gcaufy'; this.$nextTick().then(function () { console.log('UI updated'); });
自定义事件处理函数
能够经过使用.user
修饰符为自定义组件绑定事件,如:@customEvent.user="myFn"
其中,@
表示事件修饰符,customEvent
表示事件名称,.user
表示事件后缀。
目前总共有三种事件后缀:
.default
: 绑定小程序冒泡型事件,如bindtap
(.default
后缀可省略不写);
.stop
: 绑定小程序捕获型事件,如catchtap
;
.user
: 绑定用户自定义组件事件,经过$emit
触发。注意,若是用了自定义事件,则events中对应的监听函数不会再执行。
// index.wpy <template> <child @childFn.user="parentFn"></child> </template> <script> import wepy from 'wepy' import Child from '../components/child' export default class Index extends wepy.page { components = { child: Child } methods = { parentFn (num, evt) { console.log('parent received emit event, number is: ' + num) } } } </script>
// child.wpy <template> <view @tap="tap">Click me</view> </template> <script> import wepy from 'wepy' export default class Child extends wepy.component { methods = { tap () { console.log('child is clicked') this.$emit('childFn', 100) } } } </script>
slot组件内容分发插槽
首先在子组件template
模板部分中声明slot
标签做为内容插槽,同时必须在其name
属性中指定插槽名称,还可设置默认的标签内容;而后在引入了该带有插槽的子组件的父组件template
模板部分中声明用于“插拔”的内容分发标签。这些父组件中的内容分发标签必须具备slot
属性,而且其值为子组件中对应的插槽名称name。
子组件
<view class="panel"> <slot name="title">默认标题</slot> <slot name="content">默认内容</slot> </view>
父组件
<panel> <view slot="title">新的标题</view> <view slot="content"> <text>新的内容</text> </view>