评论

微信小程序页面之间正向传值和逆向传值的方法

微信小程序页面之间正向传值和逆向传值的方法

微信小程序页面之间正向传值和逆向传值

正向传值

一 直接使用URL传值
  wx.navigateTo({
      url: `/pages/contacts-edit/contacts-edit?name=zhangsan&idx=1`,
    })

但是如果一个对象结构比较复杂, 数据量比较大, 即使转换成JSON也有可能会被莫名其妙的截取.
所以使用URL传值的时候, 需要先编码
我是这样做的

// A页面触发事件, 跳转到B页面
  _onClickCell: function (e) {
	   let contacts = {
    	name: '张三',
        phone: '13800001111',
        safePhone: '138****1111',
        idCard: '230524202113324455',
        safeIdCard: '230524********4455',
        typeStr: '成人',
        gender: '0',
        genderStr: '保密'
    }
    // 先对数据进行JSON
    let jsonStr = JSON.stringify(contacts)
    // 对数据进行URI编码, 如果不进行这一步操作, 数据有可能会被截断, 少量数据没有问题, 如果是一个大的对象, 就容易被截断获取不到完整的数据
    let data = encodeURIComponent(jsonStr)

    wx.navigateTo({
      url: `/pages/contacts-edit/contacts-edit?contacts=${data}&idx=${idx}`,
    })  
  },
  
  // B页面再onLoad方法中接收参数
onLoad: function (options) {
    let idx = (!!options.idx) ? Number(options.idx) : -1
    let contacts = {}
    if (!!options.contacts) {
      let jsonStr = decodeURIComponent(options.contacts)
      contacts = JSON.parse(jsonStr)
    }
    this.setData({ contacts, idx })
  },
二 使用eventChannel来传递
//A页面准备跳转到B页面
_onClickCell: function (e) {
  let address =  {
    	id: 457,
        name: '小艾-3',
    	countryCode: '86',
    	phone: '13892292222',
    	reginoCode: '871',
    	city: '市辖区',
    	area: '海淀区',
    	street: '东北旺路8号院中关村软件园8号楼华夏科技大厦',
    	address: '中国北京市市辖区海淀区东北旺路8号院中关村软件园8号楼华夏科技大厦'
  },

    wx.navigateTo({
      url: '/pages/address-edit/address-edit',
      success: res => {
        // 这里给要打开的页面传递数据.  第一个参数:方法key, 第二个参数:需要传递的数据
        res.eventChannel.emit('setAddressEditData', address)
      }
    })
  }

//B页面在onLoad方法中接收参数
  onLoad: function (options) {
    // 接收上个页面传递来的数据
    let eventChannel = this.getOpenerEventChannel()
    // setAddressEditData和上个页面设置的相同即可
    eventChannel.on('setAddressEditData', (address) => {
      this.setData({  
      	address: address || {},
      })
    })
  },

逆向传值

一 使用全局对象, 获取全部页面来逆向传值
 _onClickComplete: function () {
// 获取当前全部的页面栈
   let arr = getCurrentPages()    
 // 获取到要逆向传值的上一个页面
   let lastPage = (arr.length >= 2) ? arr[arr.length - 2] : undefined
  // 判断拿到的上一个页面是不是我们要的页面 
   if (!!lastPage && lastPage.route == 'pages/contacts-list/contacts-list') {
      /* 
      这里我们就拿到了上一个页面的页面对象, 这里其实我们就可以使用lastPage做很多事情了, 
      例如直接操作lastPage.data, 修改上一个页面的数据  
      或者调用这个页面内的方法,
      我上一个页面预留了一个更新方法, 所以这里就直接用上一个页面调用数据刷新的方法, 我这里给赋值, 就可以携带数据回上一个页面了
      */
      lastPage.updateContactList(this.data.contacts, this.data.idx)
      // 返回上一个页面
      wx.navigateBack()      
    }
  },
二 使用eventChannel来逆向传值 B->A
// B页面
  _onClickComplete: function (e) {
    let eventChannel = this.getOpenerEventChannel()
    // updateAddressListData 这个方法需要上一个页面的支持, 上一个页面在navigateTo方法中的events数据中定义这个方法来接收数据
    eventChannel.emit('updateAddressListData', this.data.address, this.data.idx)
    wx.navigateBack()
  },
  
  // A页面需要的支持
 _onClickCell: function (e) {
    wx.navigateTo({
      url: '/pages/address-edit/address-edit',
      events: {
        // 这里用来接收后面页面传递回来的数据
        updateAddressListData: (address, index) => {
         	// 这里处理数据即可
        }
      } 
    })
  }


代码片段

最后一次编辑于  2020-07-21  
点赞 14
收藏
评论

6 个评论

  • Jacob
    Jacob
    2020-07-21
    使用eventChannel正向+逆向传值,方便且优雅。
    2020-07-21
    赞同 1
    回复 3
    • error
      error
      2020-07-22
      我的代码片段里就是这样处理的, 只不过这个需要版本适配. 第一次写这种东西, 这个是我开发过程中遇到的问题, 就写一下.
      2020-07-22
      回复
    • 你的名字
      你的名字
      2022-07-21
      NO,正向并不优雅,正向还不如使用globalData,逆向倒是挺优雅的
      2022-07-21
      回复
    • 你的名字
      你的名字
      2022-07-21
      正向不优雅的原因是因为B页面要监听事件,而且还要在onUnload中取消监听
      2022-07-21
      回复
  • 风马牛不相及
    风马牛不相及
    2023-05-15

    Emitter 自定义传值太合适

    2023-05-15
    赞同
    回复
  • 123
    123
    2021-03-05

    讲的真好,终于搞懂小程序正向逆向传值方式了

    2021-03-05
    赞同
    回复
  • 阿巴阿巴
    阿巴阿巴
    2021-02-22

    wx.miniProgram.navigateTo 呢?

    2021-02-22
    赞同
    回复
  • ×
    ×
    2020-09-28

    大佬今天用这个进行页面传值的时候遇到一个问题,A页面传递一个data中定义的变量,是引用类型(如数组)给B页面,B页面用自己的data中的一个变量去接收,然后在B页面通过push方法操作接收数据的那个变量的时候,会同步改变A页面的数据.....



    2020-09-28
    赞同
    回复 2
    • error
      error
      2021-05-11
      你的写法有问题呀, 你改变data的数据的时候, 没有使用setData() 函数. 这样会有问题的. 如果是引用出现问题. 那么可以用属性展开.
      2021-05-11
      回复
    • ×
      ×
      2021-10-09回复error
      没有用setData只影响页面现实的问题,js本身中应该不会被影响吧,我这个示例只是为了说明如果通过这种方式进行数据传递是否需要考虑引用类型的时候需要浅拷贝一下?展开我试过,如果数据深度比较复杂的情况下展开也没用,还是会出现互相影响的问题
      2021-10-09
      回复
  • Hey,Jude!
    Hey,Jude!
    2020-09-18

    讲得太好了,这就是我要的东西,文档那里看不清楚

    2020-09-18
    赞同
    回复
登录 后发表内容