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']
  }
})

 

posted @ 2024-04-24 12:59  野码  阅读(157)  评论(0编辑  收藏  举报