子组件直接调用父组件方法
我们先写一个header组件,组件左侧为返回按钮,中间为标题,正常情况左侧按钮被点击时应该返回上一级,但某些场景下,我们可能希望它不要返回上一级,而是跳转到指定页面。
需求有了,我们来梳理实现思路,父组件可以给子组件传一个跳转的方法,子组件返回按钮被点击,我们先判断父组件是否有传进来返回方法,如果有直接调用父组件的方法,如果没有直接返回上一级。
子组件
示例代码所以样式就没写,样式也不是重点
1 2 3 4 5 6
| <view class="header"> <view class="back" bindtap="handleBack">返回</view> <view class="content"> <slot></slot> </view> </view>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| Component({ properties: { customBack: { type: null, value: undefined, } }, methods: { handleBack() { const { customBack} = this.data; if (customBack) { customBack(); return; } wx.navigateBack(); }, } })
|
父组件
json文件引入也不写了,这是基础
1 2 3
| <view class="page"> <Header customBack="backFn">页面标题</Header> </view>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Page({
data: { backFn() { console.log('这就是要给子组件传的返回方法,这个方法必须得写在data中,作为普通方法写在data外面,经测试无法传进子组件'); wx.redirectTo({ url: '填写你要跳转的路径,用哪个路由跳转方法随意,redirectTo是我随便写的' }) }, }, })
|
将常规组件改造为通过JS调用
有没有遇到过产品设计的提示框或者确认框,与小程序本身的不一样得情况。
写一个自定义提示组件,来通过js的来调用。
子组件
示例代码,无样式
1 2 3 4 5 6 7
| <view class="container" wx:if="{{isShow}}"> <view class="contant"> <view class="title">{{title}}</view> <view class="text">{{content}}</view> <view class="btn" catchtap="hidden">我知道了</view> </view> </view>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| Component({ data: { isShow: false, title: '', content: '', }, methods: { show({title = '温馨提示',content = ''}) { this.setData({ isShow: true, title, content }) }, hidden() { this.setData({ isShow: false, title: '', content: '', }) } } })
export const showModal = (options, self) => { const { id = '#modal' } = options; const ctx = self.selectComponent(id); ctx.show(options); return ctx; }
|
父组件
json引入组件就不写了
1 2 3 4 5
| <view class="page"> <!-- 组件id很重要 --> <modal id="modal"></modal> <view class="btn" bindtap="handleBtnClick">弹出提示框</view> </view>
|
1 2 3 4 5 6 7 8
| import {showModal} from 'modal.js'; Page({ handleBtnClick() { // 如果组件的id与默认id不同,就需要在传个id进去 showModal({title: '提示', content: '您的操作很危险'}, this); } })
|
小程序的计算属性observers
observers
是小程序自带的数据监听器,在某些场景下是可以做为计算属性来使用的。小程序也提供了计算属性的扩展包 ,但不在这块讲解范围内。
在做表单提交的时候,我们经常需要在表单所有的必填项填完之后才允许用户点击提交按钮,在填完之前表单一直是禁用状态,此时就可以使用observers
。
示例模拟代码
1 2 3 4 5 6 7 8 9 10 11 12 13
| <view class="page"> <view class="form"> <view class="item"> <view class="label">姓名:</view> <input data-key="name" bindinput='handleInput'/> </view> <view class="item"> <view class="label">简介:</view> <input data-key="description" bindinput='handleInput'/> </view> <button disabled="disabled">提交</button> </view> </view>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| Component({ data: { name: '', description: '', disabled: true, }, observers: { 'name,description': function(name,description) { this.setData({disabled: !Boolean(name && description)}); } }, methods: { handleInput({detail: {value}, target: {dataset: {key}}}) { this.setData({ [key]: value }) } } })
|
通过Component()来定义页面
像上个例子的observers
用来处理表单提交非常好用,但遗憾的是这个方法只能在组件中使用,不能再page中使用。而且小程序的自定义组件behaviors
,page中就不能使用,所以我们就想怎么使用Component()
来构造页面。幸好腾讯提供了使用Component()
构造页面的方法,接下来我们就把上个例子改成用Component()
构造。
第一步
在页面的页面json
文件中添加usingComponents
内容
1 2 3
| { "usingComponents": {} }
|
第二步
普通页面是page()
构造的,我们将page
改成component
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| Component({ data: { name: '', description: '', disabled: true, }, observers: { 'name,description': function(name,description) { this.setData({disabled: !Boolean(name && description)}); } }, methods: { handleInput({detail: {value}, target: {dataset: {key}}}) { this.setData({ [key]: value }) } } })
|
第三步
正常从其他页面通过路径传过来的参数我们通过onLoad(options){}
来接收,通过component
构造的页面接收参数就需要properties
来接收,例如:
访问页面 /pages/detail/index?id=123&type=2
,对于参数我们就需要这么接收
1 2 3 4 5 6 7 8
| Component({ properties: { id: Number, type: Number, }, })
|
第四步
页面的声明周期在普通页面是与data
平级的,在使用component
构造页面后,页面的生命周期 就需要写在methods
中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| onLoad: function() { this.data.paramA this.data.paramB } Component({ properties: { id: Number, type: Number, }, methods: { onLoad() {}, onShow() {}, } })
|
父组件覆盖子组件样式
子组件使用 externalClasses 接收外部样式
使用 ~ 引用页面样式、使用 ^ 引用父组件或祖先组件样式
小程序的抽象节点