03_微信小程序页面之间的数据通信
1. 父传值子,数据绑定: properties
Component({ properties: { propA: { type: String, // 传递的数据类型 value: '' // 默认值 }, propB: Number // 简化的定义方式 } })
<!-- 引用组件的页面模板 --> <view> <costom propA="{{ name }}" propB="{{ age }}" /> </view>
2. 获取子组件实例:this.selectComponent()
<!-- 父组件 --> <costom bind:myevent="getData" class="custom" /><!--子组件--> <button bindtap="getChildComponent"></button>
// 父组件 Page({ data: {}, getChildComponent: function () { const child = this.selectComponent('.custom') console.log(child) } })
3. 子传父,事件绑定:this.triggerEvent()
自定义组件:
<!-- 在自定义组件中 --> <button type="primary" plain bindtap="sendData">传递数据</button>
Component({ // 组件的初始数据 data: { num: 666 }, // 组件的方法列表 methods: { // 将数据传递给父组件 sendData () { // 如果需要将数据传递给父组件 // 需要使用 triggerEvent 发射自定义事件 // 第二个参数,是携带的参数 this.triggerEvent('myevent', this.data.num) } } })
父组件中:
<view>{{ num }}</view> <!-- 需要在自定义组件标签上通过 bind 方法绑定自定义事件,同时绑定事件处理函数 --> <custom05 bind:myevent="getData" />
Page({ data: { num: '' }, getData (event) { // 可以通过事件对象.detail 获取子组件传递给父组件的数据 // console.log(event) this.setData({ num: event.detail }) } })
4. 获取应用实例:getApp()
app.js
App({ // 全局共享的数据 globalData: { token: '' }, // 全局共享的方法 setToken (token) { // 如果想获取 token,可以使用 this 的方式进行获取 this.globalData.token = token // 在 App() 方法中如果想获取 App() 实例,可以通过 this 的方式进行获取 // 不能通过 getApp() 方法获取 } })
index.js
// getApp() 方法用来获取全局唯一的 App() 实例 const appInstance = getApp() Page({ login () { // 不要通过 app 实例调用钩子函数 console.log(appInstance) appInstance.setToken('fghioiuytfghjkoiuytghjoiug') } })
5. 页面间通信:EventChannel
a.js
Page({ // 点击按钮触发的事件处理函数 handler () { wx.navigateTo({ url: '/pages/list/list', events: { // key:被打开页面通过 eventChannel 发射的事件 // value:回调函数 // 为事件添加一个监听器,获取到被打开页面传递给当前页面的数据 currentevent: (res) => { console.log(res) } }, success (res) { // console.log(res) // 通过 success 回调函数的形参,可以获取 eventChannel 对象 // eventChannel 对象给提供了 emit 方法,可以发射事件,同时携带参数 res.eventChannel.emit('myevent', { name: 'tom' }) } }) } })
b.js
Page({ onLoad () { // 通过 this.getOpenerEventChannel() 可以获取 EventChannel 对象 const EventChannel = this.getOpenerEventChannel() // 通过 EventChannel 提供的 on 方法监听页面发射的自定义事件 EventChannel.on('myevent', (res) => { console.log(res) }) // 通过 EventChannel 提供的 emit 方法也可以向上一级页面传递数据 // 需要使用 emit 定义自定义事件,携带需要传递的数据 EventChannel.emit('currentevent', { age: 10 }) } })
6. 事件总线:pubsub-js
安装命令:npm install pubsub-js
使用publish发布消息
import { publish } from 'pubsub-js' publish('dataId',data)
使用subscribe函数订阅消息
import { subscribe } from 'pubsub-js' subscribe('dataId',(msg,val)=>{ console.log('dataId值',val) console.log(msg) })
7.mobx-miniprogram和mobx-miniprogram-bindings工具库
mobx-miniprogram 的作用:创建 Store 对象,用于存储应用的数据
mobx-miniprogram-bindings 的作用:将状态和组件、页面进行绑定关联,从而在组件和页面中操作数据
安装:npm install mobx-miniprogram mobx-miniprogram-bindings
numstore.js
// observable:用于创建一个被监测的对象,对象的属性就是应用的状态(state),这些状态会被转换成响应式数据。 // action:用于显式的声明创建更新 state 状态的方法 import { observable, action } from 'mobx-miniprogram' // 使用 observable 创建一个被监测的对象 export const numStore = observable({ // 创建应用状态 numA: 1, numB: 2, // 使用 action 更新 numA 以及 numB update: action(function () { this.numA+=1 this.numB+=1 }), // 计算属性,使用 get 修饰符, get sum() { return this.numA + this.numB; } })
组件.js
导入的数据fields会同步到组件的 data 中
导入的方法actions会同步到组件的 methods 中
import { ComponentWithStore } from 'mobx-miniprogram-bindings' import { numStore } from '../../stores/numstore' ComponentWithStore({ data: { someData: '...' }, storeBindings: { store: numStore, fields: ['numA', 'numB', 'sum'], actions: ['update'] } })
页面.js和组件.js写法一样。
绑定多个 store 以及命名空间:
storeBindings内可以绑定多个store对象
// behaviors.js import { BehaviorWithStore } from 'mobx-miniprogram-bindings' import { numStore } from '../../stores/numstore' export const indexBehavior = BehaviorWithStore({ storeBindings: [ { namespace: 'numStore', store: numStore, fields: ['numA', 'numB', 'sum'], actions: ['update'], } ] })
页面.js
import { cartBehavior } from './behaviors' Page({ behaviors:[cartBehavior ] })
<view>{{ numStore.numA }} + {{ numStore.numB }} = {{numStore.sum}}</view>
storeBindings中fields和actions采用对象写法:
fields: { // 使用函数方式获取 Store 中的数据 a: () => store.numA, b: () => store.numB, // 使用映射形式获取 Store 中的数据,值为数据在 store 中对应的名字 total: 'sub' }, // 使用映射形式获取 Store 中的 action 名字 actions: { // key 自定义,为当前组件中调用的方法 // 值为 store 中对应的 action 名字 buttonTap: 'update' }
08.miniprogram-computed工具库
安装命令:npm install miniprogram-computed
该工具库提供了两个功能:
1. 计算属性 computed
2. 监听器 watch
// 引入 miniprogram-computed import { ComponentWithComputed } from 'miniprogram-computed' ComponentWithComputed({ data: { a: 1, b: 1 }, computed: { total(data) { // 注意: // computed 函数中不能访问 this ,只有 data 对象可供访问 // 这个函数的返回值会被设置到 this.data.sum 字段中 return data.a + data.b } } watch: { // 同时对 a 和 b 进行监听 'a, b': function (a, b) { this.setData({ total: a + b }) } }, methods: { updateData() { this.setData({ a: this.data.a + 1, b: this.data.b + 1 }) } } })
Mobx 与 Computed 结合使用
1. 使用旧版 API
- 自定义组件仍然使用 Component 方法构建组件,将两个扩展依赖包的使用全部改为旧版 API
- [mobx-miniprogram-bindings 官方文档](https://www.npmjs.com/package/mobx-miniprogram-bindings)
- [miniprogram-computed 官方文档](https://www.npmjs.com/package/miniprogram-computed)
2. 使用兼容写法
- 即要么使用 ComponentWithStore 方法构建组件,要么使用 ComponentWithComputed 方法构建组件
- 如果使用了 ComponentWithStore 方法构建组件,计算属性写法使用旧版 API
- 如果使用了 ComponentWithComputed 方法构建组件,Mobx写法使用旧版 API
如果使用了 ComponentWithStore 方法构建组件,计算属性写法使用旧版 API
import { ComponentWithComputed } from 'miniprogram-computed' // component.js const computedBehavior = require('miniprogram-computed').behavior ComponentWithStore({ behaviors: [computedBehavior], data: { a: 1, b: 1, sum: 2 }, watch: { 'a, b': function (a, b) { this.setData({ total: a + b }) } }, computed: { total(data) { // 注意: computed 函数中不能访问 this ,只有 data 对象可供访问 // 这个函数的返回值会被设置到 this.data.sum 字段中 return data.a + data.b + data.sum // data.c 为自定义 behavior 数据段 } }, // 实现组件和 Store 的关联 storeBindings: { store: numStore, // fields 和 actions 有两种写法:数组写法 和 对象写法 // 数组写法 fields: ['numA', 'numB', 'sum'], actions: ['update'] } })
使用了 ComponentWithComputed方法构建组件,Mobx写法使用旧版 API
import { ComponentWithComputed } from 'miniprogram-computed' // 导入 storeBindingsBehavior 方法实现组件和 Store 的关联 import { storeBindingsBehavior } from "mobx-miniprogram-bindings" // 导入 Store import { numStore } from '../../stores/numstore' ComponentWithComputed({ behaviors: [storeBindingsBehavior], data: { a: 1, b: 1, sum: 2 }, watch: { 'a, b': function (a, b) { this.setData({ total: a + b }) } }, computed: { total(data) { // 注意: computed 函数中不能访问 this ,只有 data 对象可供访问 // 这个函数的返回值会被设置到 this.data.sum 字段中 return data.a + data.b + data.sum // data.c 为自定义 behavior 数据段 } }, // 实现组件和 Store 的关联 storeBindings: { store: numStore, // fields 和 actions 有两种写法:数组写法 和 对象写法 // 数组写法 fields: ['numA', 'numB', 'sum'], actions: ['update'] } })