微信小程序调试报错:onLoad, selectMode:
这个问题的根因非常典型,是微信小程序 tabBar 页面的跳转限制导致的。
页面被配置成了 tabBar 页面(app.json 里明确写了),而你在 inbound.js 里用的是 wx.navigateTo 跳转它:

// inbound.js 里的错误跳转方式
wx.navigateTo({
  url: '/pages/inventory/inventory?selectMode=1', // ❌ 违规!
  events: { ... }
});

微信小程序的硬性规则:
tabBar 配置的页面,只能用 wx.switchTab 跳转,不能用 wx.navigateTo
wx.navigateTo 跳 tabBar 页面会被框架拦截,参数无法正常传递,所以你在 onLoad 里拿到的 options.selectMode 永远是 undefined。
之前能打开页面是因为旧基础库的兼容漏洞,但参数已经被拦截了,所以控制台打印
两种解决方案(推荐方案一,最规范)

方案一:新增「商品选择页」(强烈推荐,行业标准做法)
和京东/淘宝的「选择收货地址」逻辑一样:tabBar 里的「库存」是浏览页,单独做一个「选择商品」的普通页面用于入库/出库等场景,互不干扰。
操作步骤:
1、复制 inventory 页面,重命名为 select-product

pages/
├── inventory/inventory  # tabBar的库存浏览页
└── select-product/select-product  # 新增的商品选择页(复制inventory的所有文件)

2、修改 select-product 的逻辑
只需要保留选择相关的逻辑,删除不需要的入口(比如「管理分类」可以保留,也可以隐藏)。
3、修改 inbound.js 的跳转路径

// inbound.js 修正跳转
wx.navigateTo({
  url: '/pages/select-product/select-product', // ✅ 普通页面,允许navigateTo
  events: {
    onProductSelected: (product) => {
      this.onProductSelected(product);
    }
  }
});

4、select-product 的 emitToOpener 用我们之前改的稳定版

emitToOpener(product) {
  console.log('[select-product] 选择商品:', product.name);
  // 优先用EventChannel,兜底用getCurrentPages
  const channel = this.getOpenerEventChannel();
  if (channel && typeof channel.emit === 'function') {
    channel.emit('onProductSelected', product);
    setTimeout(() => wx.navigateBack(), 50);
    return;
  }
  // 兜底逻辑
  const pages = getCurrentPages();
  const prevPage = pages[pages.length - 2];
  if (prevPage && typeof prevPage.onProductSelected === 'function') {
    prevPage.onProductSelected(product);
    wx.navigateBack();
  }
},

✅ 优点:完全符合小程序规范,参数传递、事件通信100%稳定,后续扩展性强。
方案二:不新增页面,改造现有 inventory 页面(兼容现有逻辑)
如果一定要共用 inventory 页面,需要绕过 tabBar 的限制,核心思路是:不用 selectMode 参数,通过判断上一页的方法是否存在来决定是否回传。
操作步骤:
1、inbound.js 改用 wx.switchTab 跳转

// inbound.js 修正跳转
wx.switchTab({
  url: '/pages/inventory/inventory' // ✅ switchTab跳tabBar页面
});
// 临时存选择回调(因为switchTab不支持events)
this._productSelectCallback = (product) => {
  this.onProductSelected(product);
};

2、删除 inventory.js 里所有 selectMode 相关逻辑

// inventory.js onLoad 删掉这些
// this.setData({
//   selectMode: options?.selectMode === '1',
//   role: options?.role || '',
//   isSelectMode: options?.selectMode === '1'
// });

3、改造 emitToOpener,自动判断是否需要回传

emitToOpener(product) {
  console.log('[inventory] 点击商品:', product.name);
  // 取上一页
  const pages = getCurrentPages();
  const prevPage = pages[pages.length - 2];
  // 判断上一页有没有onProductSelected方法(只有入库/出库等页才有)
  if (prevPage && typeof prevPage.onProductSelected === 'function') {
    prevPage.onProductSelected(product);
    wx.navigateBack();
    return;
  }
  // 没有的话,说明是从tabBar进入的,走商品详情逻辑
  wx.navigateTo({
    url: `/pages/product-detail/product-detail?id=${product.id}`
  });
},

✅ 优点:不需要新增页面,改动量小。

❌ 缺点:逻辑耦合,后续扩展容易出问题。
这个问题的根因非常典型,是微信小程序 tabBar 页面的跳转限制导致的,我给你拆解得明明白白👇

❌ 100% 确定的根因

你的 inventory 页面被配置成了 tabBar 页面(app.json 里明确写了),而你在 inbound.js 里用的是 wx.navigateTo 跳转它:

js
// inbound.js 里的错误跳转方式
wx.navigateTo({
url: '/pages/inventory/inventory?selectMode=1', // ❌ 违规!
events: { ... }
});
微信小程序的硬性规则:

tabBar 配置的页面,只能用 wx.switchTab 跳转,不能用 wx.navigateTo

wx.navigateTo 跳 tabBar 页面会被框架拦截,参数无法正常传递,所以你在 onLoad 里拿到的 options.selectMode 永远是 undefined。

你之前能打开页面是因为旧基础库的兼容漏洞,但参数已经被拦截了,所以控制台打印

✅ 两种解决方案(推荐方案一,最规范)
方案一:新增「商品选择页」(强烈推荐,行业标准做法)

和京东/淘宝的「选择收货地址」逻辑一样:tabBar 里的「库存」是浏览页,单独做一个「选择商品」的普通页面用于入库/出库等场景,互不干扰。

操作步骤:

复制 inventory 页面,重命名为 select-product

纯文本
pages/
├── inventory/inventory # tabBar的库存浏览页
└── select-product/select-product # 新增的商品选择页(复制inventory的所有文件)

修改 select-product 的逻辑

只需要保留选择相关的逻辑,删除不需要的入口(比如「管理分类」可以保留,也可以隐藏)。

修改 inbound.js 的跳转路径

js
// inbound.js 修正跳转
wx.navigateTo({
url: '/pages/select-product/select-product', // ✅ 普通页面,允许navigateTo
events: {

onProductSelected: (product) => {
  this.onProductSelected(product);
}

}
});

select-product 的 emitToOpener 用我们之前改的稳定版

js
emitToOpener(product) {
console.log('[select-product] 选择商品:', product.name);
// 优先用EventChannel,兜底用getCurrentPages
const channel = this.getOpenerEventChannel();
if (channel && typeof channel.emit === 'function') {

channel.emit('onProductSelected', product);
setTimeout(() => wx.navigateBack(), 50);
return;

}
// 兜底逻辑
const pages = getCurrentPages();
const prevPage = pages[pages.length - 2];
if (prevPage && typeof prevPage.onProductSelected === 'function') {

prevPage.onProductSelected(product);
wx.navigateBack();

}
}

✅ 优点:完全符合小程序规范,参数传递、事件通信100%稳定,后续扩展性强。

方案二:不新增页面,改造现有 inventory 页面(兼容现有逻辑)

如果一定要共用 inventory 页面,需要绕过 tabBar 的限制,核心思路是:不用 selectMode 参数,通过判断上一页的方法是否存在来决定是否回传。

操作步骤:

inbound.js 改用 wx.switchTab 跳转

js
// inbound.js 修正跳转
wx.switchTab({
url: '/pages/inventory/inventory' // ✅ switchTab跳tabBar页面
});
// 临时存选择回调(因为switchTab不支持events)
this._productSelectCallback = (product) => {
this.onProductSelected(product);
};

删除 inventory.js 里所有 selectMode 相关逻辑

js
// inventory.js onLoad 删掉这些
// this.setData({
// selectMode: options?.selectMode === '1',
// role: options?.role || '',
// isSelectMode: options?.selectMode === '1'
// });

改造 emitToOpener,自动判断是否需要回传

js
emitToOpener(product) {
console.log('[inventory] 点击商品:', product.name);
// 取上一页
const pages = getCurrentPages();
const prevPage = pages[pages.length - 2];

// 判断上一页有没有onProductSelected方法(只有入库/出库等页才有)
if (prevPage && typeof prevPage.onProductSelected === 'function') {

prevPage.onProductSelected(product);
wx.navigateBack();
return;

}

// 没有的话,说明是从tabBar进入的,走商品详情逻辑
wx.navigateTo({

url: `/pages/product-detail/product-detail?id=${product.id}`

});
},

✅ 优点:不需要新增页面,改动量小。

❌ 缺点:逻辑耦合,后续扩展容易出问题。

🔍 30秒验证根因
可以临时把 inventory 从 app.json 的 tabBar.list 里删掉,再测试跳转:

// app.json 临时注释inventory的tab配置
"tabBar": {
  "list": [
    { "pagePath": "pages/index/index", ... },
    // { "pagePath": "pages/inventory/inventory", ... },
    { "pagePath": "pages/stats/stats", ... }
  ]
}

如果这时候 onLoad 里能打印出 selectMode: "1",就100%证明是 tabBar 跳转限制导致的。

🎯 一句话总结
❌ 根因:inventory 是 tabBar 页面,用 wx.navigateTo 跳转会被拦截,参数无法传递

✅ 最优解:新增独立的 select-product 普通页面用于选品,彻底避开 tabBar 限制

✅ 应急解:改用 wx.switchTab 跳转,通过判断上一页方法是否存在来实现回传

最后修改:2026 年 08 月 04 日
如果觉得我的文章对你有用,请随意赞赏