Skip to content

原生微信小程序开发遇到的问题记录

1. 如何引入微信小程序组件库

https://tdesign.tencent.com/miniprogram/getting-started

  1. 使用 NPM

    npm i tdesign-miniprogram -S --production
  2. 修改 app.json

    将 app.json 中的 "style": "v2" 移除。

    因为 该配置 表示启用新版组件样式,将会导致 TDesign 的组件样式错乱。

  3. 微信小程序开发者代码编辑器 - 工具 - 构建 npm

2. 自定义底部 tabbar (不生效)

2.1 在 app.json 添加 tabBar

json
"tabBar": {
    "custom": true,
    "list": [
      {
        "pagePath": "pages/home/home",
        "text": "首页"
      },
      {
        "pagePath": "pages/plaza/plaza",
        "text": "广场"
      },
      {
        "pagePath": "pages/me/me",
        "text": "我的"
      }
    ]
  },

2.2 根目创建一个 custom-tab-bar 目录

代码参考 https://tdesign.tencent.com/miniprogram/components/tab-bar#图标加文字标签栏

js
Component({
  data: {
    value: "home",
    list: [
      {
        value: "home",
        label: "首页",
        icon: "home",
        pagePath: "pages/home/home",
      },
      {
        value: "plaza",
        label: "广场",
        icon: "chat",
        pagePath: "pages/plaza/plaza",
      },
      { value: "me", label: "我的", icon: "user", pagePath: "pages/me/me" },
    ],
  },
  methods: {
    onChange(e) {
      this.setData({
        value: e.detail.value,
      });
      const selectedPage = this.data.list.find(
        (item) => item.value === e.detail.value
      );
      if (selectedPage) {
        wx.switchTab({
          url: `/${selectedPage.pagePath}`,
        });
      }
    },
    init() {
      const page = getCurrentPages().pop();
      const route = page ? page.route.split("?")[0] : "";
      const active = this.data.list.findIndex(
        (item) => item.pagePath === `${route}`
      );
      this.setData({ active, value: this.data.list[active].value });
    },
  },
});

2.3 需要显示的页面中调用 init 方法

  • pages/home/home
  • pages/plaza/plaza
  • pages/me/me
js
  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {
    this.getTabBar().init();
  },

2.4 最终效果

alt text

3. 如何修改小程序顶部的名称

alt text

页面的 home.json

https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/page.html

json
{
  "navigationBarTitleText": "首页",
  "onReachBottomDistance": 10,
  "backgroundTextStyle": "light",
  "enablePullDownRefresh": true,
  "usingComponents": {}
}

4. scroll-view 组件高度的问题

可滚动视图区域。使用竖向滚动时,需要给 scroll-view 一个固定高度,通过 WXSS 设置 height。

组件属性的长度单位默认为 px,2.4.0 起支持传入单位(rpx/px)

https://developers.weixin.qq.com/miniprogram/dev/component/scroll-view.html

下面是解决方案

css
/* pages/home/home.wxss */
page {
  box-sizing: border-box;
  padding-bottom: calc(env(safe-area-inset-bottom) + 96rpx);
  display: flex;
  flex-direction: column;
}
.scroll-content {
  height: calc(100vh - 64rpx - 96rpx - env(safe-area-inset-bottom));
}

其中,

  • padding-bottom: calc(env(safe-area-inset-bottom) + 96rpx)是官方给的代码,距离底部有一个安全的距离
  • 64rpx 是搜索框的高度

alt text

5. t-dialog 无法打开,引入就是失败

  1. 删掉 node_modules
  2. 删掉 miniprogram_npm
  3. 关闭微信小程序编辑器
  4. npm i -f
  5. 工具 - 构建 npm
  6. 编译

alt text

6. 自定义导航栏 navigationBar

https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html#window

alt text

微信小程序 自定义导航栏 navigationBar https://blog.csdn.net/qq_27981847/article/details/131984483

6.1 把要自定义导航栏的页面的 json 配置添加"navigationStyle":"custom"配置

json
{
  "navigationBarTitleText": "广场",
  "navigationStyle": "custom",
  "backgroundTextStyle": "light",
  "usingComponents": {
    "t-tabs": "tdesign-miniprogram/tabs/tabs",
    "t-tab-panel": "tdesign-miniprogram/tab-panel/tab-panel",
    "navigation-bar": "../../components/navigation-bar/navigation-bar"
  }
}

6.2 app.js 中添加获取 statusBarHeight 和 navigationBarHeight,注意获取到的是 px 为单位的

js
// app.js
App({
  onLaunch() {
    const { statusBarHeight, platform, windowHeight } = wx.getSystemInfoSync();
    const { top, height } = wx.getMenuButtonBoundingClientRect();
    // 状态栏高度
    wx.setStorageSync("statusBarHeight", statusBarHeight);
    // 屏幕高度
    wx.setStorageSync("windowHeight", windowHeight);
    // 胶囊按钮高度 一般是32 如果获取不到就使用32
    wx.setStorageSync("menuButtonHeight", height ? height : 32);
    // 判断胶囊按钮信息是否成功获取
    if (top && top !== 0 && height && height !== 0) {
      const navigationBarHeight = (top - statusBarHeight) * 2 + height;
      // 导航栏高度
      wx.setStorageSync("navigationBarHeight", navigationBarHeight);
    } else {
      wx.setStorageSync(
        "navigationBarHeight",
        platform === "android" ? 48 : 40
      );
    }
  },
  globalData: {
    userInfo: null,
  },
});

6.3 navigation-bar 组件部分代码

js
// components/navigation-bar/navigation-bar.js
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    title: { type: String, value: "" },
  },

  /**
   * 组件的初始数据
   */
  data: {
    // 状态栏高度
    statusBarHeight: wx.getStorageSync("statusBarHeight"),
    // 导航栏高度
    navigationBarHeight: wx.getStorageSync("navigationBarHeight"),
    // 胶囊按钮高度
    menuButtonHeight: wx.getStorageSync("menuButtonHeight"),
  },

  /**
   * 组件的方法列表
   */
  methods: {},
});

6.4 需要自定义导航栏的地方引入该组件

json
{
  "navigationBarTitleText": "广场",
  "navigationStyle":"custom",
  "backgroundTextStyle": "light",
  "usingComponents": {
    "navigation-bar": "../../components/navigation-bar/navigation-bar"
  }
}

6.5 代码中使用

xml
<navigation-bar title="广场" />

6.6. 效果

alt text

7. 微信小程序 tdesign 组件库自定义 class 不会显示在 DOM 树上

html
<t-button t-class="custom-my-class" theme="primary" size="small" variant="text"
  >发送验证码</t-button
>
css
.custom-my-class {
  color: red !important;
}

alt text

8. t-swipe-cell 组件在真机上无法滑动

解决方案 去掉app.json或page.json的"componentFramework": "glass-easel"试试呢

相关 issues https://github.com/Tencent/tdesign-miniprogram/issues/2668

9. 微信小程序如何调用扫码功能

微信小程序调用扫码功能需要使用微信提供的wx.scanCodeAPI。以下是使用该 API 实现扫码功能的基本步骤:

  1. 权限设置:首先,你需要在微信小程序的管理后台配置相应的权限。在“开发”-“开发管理”-“功能设置”中,找到“摄像头”功能,并开启它。
  2. 编写代码:在小程序的页面中,编写调用扫码 API 的代码。具体代码示例如下:
javascript
// 在需要扫码的页面的js文件中
Page({
  // ... 其他代码
  // 调用扫码函数
  doScanCode() {
    wx.scanCode({
      onlyFromCamera: true, // 是否只能从相机扫码,不允许从相册选择图片
      scanType: ["barCode", "qrCode"], // 可以指定扫二维码还是一维码,默认二者都有
      success(res) {
        console.log(res);
        // 在这里处理扫码成功后的逻辑,例如将结果展示给用户
        wx.showToast({
          title: "扫码成功",
          icon: "success",
          duration: 2000,
        });
      },
      fail(err) {
        // 扫码失败的回调
        console.log(err);
        wx.showToast({
          title: "扫码失败",
          icon: "none",
          duration: 2000,
        });
      },
    });
  },
  // ... 其他代码
});
  1. 用户触发:在小程序的页面中,通过用户的某个操作(例如点击按钮)来触发扫码功能。例如,可以在页面的wxml文件中添加一个按钮:
html
<button bindtap="doScanCode">扫一扫</button>

这样,当用户点击这个按钮时,就会调用doScanCode函数,进而调用摄像头进行扫码。

  1. 测试与调试:在开发过程中,你可以在微信开发者工具中测试扫码功能。确保你的摄像头在开发者工具中是可以访问的。

  2. 发布审核:完成开发后,提交小程序代码进行审核。确保你的小程序符合微信平台的相关规定,否则可能会影响审核通过。

通过以上步骤,你就可以在小程序中实现扫码功能。在实际开发中,还需要注意用户体验和隐私保护,确保扫码功能的实现既方便又安全。

10. 微信小程序跳转页面如何传参

微信小程序中,页面之间的跳转传参可以通过以下几种方式实现:

  1. 使用 URL 带参数跳转
    • wx.navigateTo或者wx.redirectTo的方法中,可以通过url属性携带参数。
    • 参数需要通过 encodeURIComponent 进行编码,以避免特殊字符导致的错误。
    • 示例代码如下:
javascript
// 跳转页面,并携带参数
wx.navigateTo({
  url: "/pages/other/other?param=" + encodeURIComponent("传递的参数"),
});
// 在目标页面中,通过onLoad函数接收参数
Page({
  onLoad: function (options) {
    var param = decodeURIComponent(options.param);
    // 使用param进行后续操作
  },
});
  1. 使用全局变量传参
    • 可以将需要传递的数据存储在全局变量中,例如小程序的全局对象App中。
    • 在页面 A 设置数据,然后在页面 B 中获取数据。
    • 示例代码如下:
javascript
// 在页面A中设置全局变量
const appInstance = getApp();
appInstance.globalData.param = "传递的参数";
// 在页面B中获取全局变量
const appInstance = getApp();
var param = appInstance.globalData.param;
// 使用param进行后续操作
  1. 使用本地存储传参
    • 通过wx.setStorageSync将数据存储在小程序的本地缓存中。
    • 然后在另一个页面通过wx.getStorageSync获取缓存的数据。
    • 示例代码如下:
javascript
// 在页面A中存储数据
wx.setStorageSync("param", "传递的参数");
// 在页面B中读取数据
var param = wx.getStorageSync("param");
// 使用param进行后续操作

请注意,在使用这些方法进行页面传参时,需要遵循微信小程序的开发规范,确保数据的安全性和隐私保护,不泄露用户敏感信息。同时,在页面跳转时,要注意控制页面层级,避免过多的页面层级导致性能问题。

11. 微信小程序如何实现手机号码一键登录

为了实现微信小程序中的手机号一键登录功能,需要前后端的协调和微信开放平台的支持。以下是基本步骤和时序图描述:

前端步骤:

  1. 引导用户点击“一键登录”按钮:
    • 用户在微信小程序的页面上点击“一键登录”按钮。
  2. 调用微信登录接口:
    • 调用wx.login()接口获取临时登录凭证(code)。
  3. 获取手机号授权:
    • 调用wx.getPhoneNumber()接口,获取用户授权后返回的加密数据(encryptedData)和初始向量(iv)。
  4. 将 code、encryptedData 和 iv 发送到后端:
    • 通过 API 将这些数据发送到后端服务器。

后端步骤:

  1. 处理前端传来的数据:
    • 接收到前端传来的codeencryptedDataiv
  2. 调用微信服务端接口获取 session_key:
    • 使用code调用微信开放平台的接口(如https://api.weixin.qq.com/sns/jscode2session),获取session_key
  3. 解密用户数据:
    • 使用session_key和前端传来的encryptedDataiv解密出用户的手机号。
  4. 生成用户登录态:
    • 根据解密出的手机号和业务逻辑生成用户的登录态(如生成 token)。
  5. 返回登录结果:
    • 将生成的登录态返回给前端。

时序图描述:

  1. 用户 -> 小程序: 点击“一键登录”按钮
  2. 小程序 -> 微信服务器: wx.login() 获取 code
  3. 微信服务器 -> 小程序: 返回 code
  4. 小程序 -> 用户: 触发手机号授权界面
  5. 用户 -> 小程序: 授权手机号
  6. 小程序 -> 微信服务器: wx.getPhoneNumber() 获取 encryptedDataiv
  7. 微信服务器 -> 小程序: 返回 encryptedDataiv
  8. 小程序 -> 后端服务器: 发送 codeencryptedDataiv
  9. 后端服务器 -> 微信服务器: 用 code 获取 session_key
  10. 微信服务器 -> 后端服务器: 返回 session_key
  11. 后端服务器: 解密 encryptedData 得到手机号
  12. 后端服务器: 生成登录态(如 token)
  13. 后端服务器 -> 小程序: 返回登录结果(token 等)
  14. 小程序 -> 用户: 登录成功

时序图示例

plaintext
用户                  小程序                微信服务器              后端服务器
 |                     |                      |                        |
 | 点击“一键登录”按钮   |                      |                        |
 | ----------------->  |                      |                        |
 |                     | wx.login()           |                        |
 |                     | ------------------>  |                        |
 |                     |                      | 返回code               |
 |                     | <------------------  |                        |
 |                     |                      |                        |
 | 触发手机号授权界面    |                      |                        |
 | <-----------------  |                      |                        |
 |                     |                      |                        |
 | 授权手机号           |                      |                        |
 | ----------------->  |                      |                        |
 |                     | wx.getPhoneNumber()  |                        |
 |                     | ------------------>  |                        |
 |                     |                      | 返回encryptedData和iv  |
 |                     | <------------------  |                        |
 |                     |                      |                        |
 | 发送code, encryptedData, iv                |                        |
 | -----------------------------------------> |                        |
 |                                           | 用code获取session_key  |
 |                                           | -------------------->  |
 |                                           | 返回session_key        |
 |                                           | <--------------------  |
 |                                           |                        |
 |                                           | 解密数据,得到手机号   |
 |                                           | 生成登录态             |
 |                                           | 返回登录结果(token)  |
 | <---------------------------------------- |                        |
 | 登录成功                                   |                        |

希望这个步骤和时序图示例能帮助你理解微信小程序手机号一键登录的实现流程。

参考地址

小程序登录 https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html

手机号快速验证组件 https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html

获取手机号 https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-info/phone-number/getPhoneNumber.html

getPhoneNumber 获取用户手机号,可以从 bindgetphonenumber 回调中获取到用户信息 https://tdesign.tencent.com/miniprogram/components/button?tab=api

代码

这里使用的是“手机号快速验证组件”

xml
<t-button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber" theme="primary" size="large" block>授权手机号一键登录</t-button>
js
Page({
  // 授权手机号一键登录
  getPhoneNumber(e) {
    console.log(e.detail.code); // 动态令牌
    console.log(e.detail.errMsg); // 回调信息(成功失败都会返回)
    console.log(e.detail.errno); // 错误码(失败时返回)

    if (e.detail.code) {
      wx.setClipboardData({
        data: e.detail.code,
        success(res) {
          wx.showToast({
            title: "动态令牌已经复制到剪切板",
            icon: "success",
            duration: 2000,
          });
        },
        fail(res) {
          wx.showToast({
            title: "复制失败",
            icon: "none",
            duration: 2000,
          });
        },
      });
    } else {
      wx.showToast({
        title: e.detail.errMsg,
        icon: "none",
        duration: 2000,
      });
    }
  },
});

12. 用户点击右上角分享

使用 onShareAppMessage(Object object) api。

注意:只有定义了此事件处理函数,右上角菜单才会显示“转发”按钮

官方文档 https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html#onShareAppMessage-Object-object

13. 微信小程序消息订阅用户端拉起弹窗

wx.requestSubscribeMessage(Object object) https://developers.weixin.qq.com/miniprogram/dev/api/open-api/subscribe-message/wx.requestSubscribeMessage.html

微信小程序 wx.requestSubscribeDeviceMessage(Object object) 和 wx.requestSubscribeMessage(Object object) 的区别是什么

wx.requestSubscribeDeviceMessagewx.requestSubscribeMessage 是微信小程序中的两个不同的 API,用于订阅消息,但它们的用途和应用场景有所不同。

wx.requestSubscribeDeviceMessage

  • 用途: 用于订阅设备消息。
  • 适用场景: 主要用于物联网(IoT)设备与微信小程序之间的消息交互。用户可以订阅来自设备的消息,比如智能家居设备的状态变化通知等。
  • 参数:
    • tmplIds: 设备消息模板 ID 的数组。
    • deviceId: 设备 ID。
    • success, fail, complete: 分别是请求成功、失败和完成后的回调函数。

wx.requestSubscribeMessage

  • 用途: 用于订阅一次性订阅消息。
  • 适用场景: 用于订阅来自微信公众平台的一次性消息,比如订阅特定事件的通知(如快递到达通知、活动提醒等)。
  • 参数:
    • tmplIds: 消息模板 ID 的数组。
    • success, fail, complete: 分别是请求成功、失败和完成后的回调函数。

具体区别总结

  • 订阅对象不同: wx.requestSubscribeDeviceMessage 订阅的是设备消息,主要用于物联网设备;而 wx.requestSubscribeMessage 订阅的是微信公众平台的一次性消息,主要用于各种通知提醒。
  • 应用场景不同: 前者适用于 IoT 设备的消息交互,后者适用于一般的通知消息。
  • 参数不同: wx.requestSubscribeDeviceMessage 需要传递 deviceId(设备 ID),而 wx.requestSubscribeMessage 不需要。

希望这些信息能帮到你更好地理解这两个 API 的区别和使用场景。

14. 微信小程序消息模板订阅(自定义模板)

如果没有合适的模板,你可以按照以下的方式进入模板申请页面

  1. 复制连接到浏览器中

    https://mp.weixin.qq.com/wxamp/newtmpl/tmpladd?simple=1&token=1302701405&lang=zh_CN

  2. 把 token 改成你登录成功的地址的 token,刷新浏览器,然后就可以了进入到模板申请页面了

如下图:

alt text

alt text

alt text

15. web-view 中显示的网页 无法打开

如下图,显示 “无法打开该页面,不支持打开”

![alt text](image-10.png)

解决办法:

  1. 要求你的小程序必须是企业的(个人的不支持 webview 显示网页)

  2. 需要把显示网页的域名,添加到 “业务域名” 中(个人的小程序没有业务域名配置项)

    alt text

16. 微信小程序中使用 css 变量

app.wxss 定义

css
/**app.wxss**/
page {
  --main-color: #3498db;
  --background-color: #f3f4f6;
}

其他页面使用

css
page {
  background-color: var(--background-color);
}

参考 https://blog.csdn.net/animatecat/article/details/128327353

17. 微信小程序开发中,有刷新 token 逻辑,1. 每一次进入应用都刷新 token 2. 进入应用判断是否过期,没有过期则不刷新 token,启动一个定时器,过期时自动刷新 token,3. 进入应用判断是否过期,没有过期则不刷新 token,每一次请求之前判断是否过期,过期则刷新 token,你建议使用哪一种

在微信小程序开发中,处理刷新 token 的逻辑需要考虑应用的安全性和用户体验。三种方式各有优缺点,具体选择取决于你的需求和应用场景。

1. 每一次进入应用都刷新 token

优点:

  • 简单易实现
  • 确保每次进入应用时,token 都是最新的

缺点:

  • 频繁刷新 token,可能会增加服务器负载
  • 用户每次进入应用都会有一个短暂的延迟,等待 token 刷新

适用场景:

  • 对安全性要求非常高,宁愿增加服务器负载和用户等待时间,也要确保 token 始终最新

2. 进入应用判断是否过期,没有过期则不刷新 token,启动一个定时器,过期时自动刷新 token

优点:

  • 减少了不必要的 token 刷新,优化了服务器负载
  • 保证了在应用使用期间,token 始终有效

缺点:

  • 定时器管理可能较为复杂
  • 需要确保定时器在应用进入后台或关闭时能正确处理

适用场景:

  • 希望在减少服务器负载的同时,保证用户在应用使用期间 token 始终有效

3. 进入应用判断是否过期,没有过期则不刷新 token,每一次请求之前判断是否过期,过期则刷新 token

优点:

  • 最为节省资源,仅在需要时刷新 token
  • 保证了请求在发出前 token 始终有效

缺点:

  • 每次请求前需要增加判断逻辑,可能会略微增加请求时间
  • 实现较为复杂,需确保在并发情况下正确处理 token 刷新

适用场景:

  • 对性能要求较高,希望尽可能减少不必要的 token 刷新
  • 需要在保证安全性的前提下,优化用户体验

推荐建议

综合考虑用户体验和服务器负载,建议选择第三种方式

  • 进入应用判断是否过期,没有过期则不刷新 token,每一次请求之前判断是否过期,过期则刷新 token

这种方式能确保 token 始终有效,避免不必要的刷新,同时在每次请求前进行检查,确保安全性。虽然实现较为复杂,但能提供最佳的用户体验和性能优化。

如果你需要实现这种逻辑,可以参考以下示例代码:

javascript
// app.js
App({
  onLaunch() {
    this.checkToken();
  },

  checkToken() {
    const token = wx.getStorageSync("token");
    const tokenExpiry = wx.getStorageSync("tokenExpiry");
    const now = new Date().getTime();

    if (!token || !tokenExpiry || now > tokenExpiry) {
      this.refreshToken();
    }
  },

  refreshToken() {
    // 模拟请求刷新 token 的接口
    wx.request({
      url: "https://api.example.com/refreshToken",
      method: "POST",
      success: (res) => {
        wx.setStorageSync("token", res.data.token);
        wx.setStorageSync(
          "tokenExpiry",
          new Date().getTime() + res.data.expires_in * 1000
        );
      },
    });
  },
});
javascript
// request.js
function request(options) {
  const token = wx.getStorageSync("token");
  const tokenExpiry = wx.getStorageSync("tokenExpiry");
  const now = new Date().getTime();

  if (!token || !tokenExpiry || now > tokenExpiry) {
    return refreshToken().then(() => {
      options.header = options.header || {};
      options.header.Authorization = `Bearer ${wx.getStorageSync("token")}`;
      return wx.request(options);
    });
  } else {
    options.header = options.header || {};
    options.header.Authorization = `Bearer ${token}`;
    return wx.request(options);
  }
}

function refreshToken() {
  return new Promise((resolve, reject) => {
    wx.request({
      url: "https://api.example.com/refreshToken",
      method: "POST",
      success: (res) => {
        wx.setStorageSync("token", res.data.token);
        wx.setStorageSync(
          "tokenExpiry",
          new Date().getTime() + res.data.expires_in * 1000
        );
        resolve();
      },
      fail: (err) => {
        reject(err);
      },
    });
  });
}

module.exports = {
  request,
};

通过这种方式,你可以确保 token 始终在请求前有效,同时尽可能减少不必要的 token 刷新。

18. 微信小程序如何分包

在微信小程序开发中,分包加载(Subpackages Loading)是一种将小程序的代码按需加载的技术,可以有效地提高小程序的启动速度和用户体验。以下是如何在微信小程序中进行分包的步骤:

1. 创建分包

在项目的根目录下创建一个文件夹用于存放分包的代码,比如subpackage1

2. 配置分包

在小程序项目的 app.json 文件中配置分包信息。添加 subpackages 字段来定义分包:

json
{
  "pages": ["pages/index/index", "pages/logs/logs"],
  "subpackages": [
    {
      "root": "subpackage1",
      "pages": ["pages/page1", "pages/page2"]
    },
    {
      "root": "subpackage2",
      "pages": ["pages/page3", "pages/page4"]
    }
  ]
}
  • root:指定分包的根目录。
  • pages:指定分包中包含的页面路径,相对于分包的根目录。

3. 编写分包页面

subpackage1 目录下创建一个 pages 文件夹,并在其中创建页面文件,例如 page1page2

subpackage1/
  └─ pages/
       ├─ page1/
       │   ├─ page1.js
       │   ├─ page1.json
       │   ├─ page1.wxml
       │   └─ page1.wxss
       └─ page2/
           ├─ page2.js
           ├─ page2.json
           ├─ page2.wxml
           └─ page2.wxss

4. 使用分包页面

在需要跳转到分包页面的地方,使用相对路径进行跳转。例如,在首页跳转到 subpackage1 下的 page1 页面:

javascript
wx.navigateTo({
  url: "/subpackage1/pages/page1/page1",
});

5. 调试与发布

在开发者工具中进行调试,确保分包加载正常。分包加载成功后,可以通过开发者工具进行预览和发布。

注意事项

  1. 主包和分包大小限制:主包大小不能超过 2MB,单个分包大小不能超过 2MB,所有分包总大小不能超过 20MB。
  2. 分包预下载:可以通过配置 subpackagesindependent 字段来指定独立分包,或者使用 preloadRule 字段来预下载分包。

例如,配置预下载规则:

json
{
  "preloadRule": {
    "pages/index/index": {
      "network": "wifi",
      "packages": ["subpackage1"]
    }
  }
}

这种配置表示在访问 pages/index/index 页面时,如果用户处于 WiFi 网络环境下,会预下载 subpackage1

这样,通过分包加载技术,可以显著提高微信小程序的加载速度和性能,提升用户体验。

19. 微信小程序分包实践

这是我的配置 app.json

json
{
  "pages": [
    "pages/home/home",
    "pages/login/login",
    "pages/plaza/plaza",
    "pages/me/me",
    "pages/me/settings/settings",
    "pages/me/download/download",
    "pages/me/want-to-watch/want-to-watch",
    "pages/me/channel/channel",
    "pages/me/devices/devices",
    "pages/me/devices/device-detail/device-detail",
    "pages/me/devices/bind-device/bind-device",
    "pages/me/devices/device-format/device-format",
    "pages/movies/search/search",
    "pages/movies/detail/detail",
    "pages/movies/result/index",
    "pages/channel/channel",
    "pages/agreement/agreement",
    "pages/report/report",
    "pages/report/form/form"
  ],
  "tabBar": {
    "custom": true,
    "list": [
      {
        "pagePath": "pages/home/home",
        "text": "首页"
      },
      {
        "pagePath": "pages/plaza/plaza",
        "text": "广场"
      },
      {
        "pagePath": "pages/me/me",
        "text": "我的"
      }
    ]
  },
  "window": {
    "backgroundTextStyle": "light",
    "navigationBarTextStyle": "black",
    "navigationBarTitleText": "圈子",
    "navigationBarBackgroundColor": "#ffffff"
  },
  "sitemapLocation": "sitemap.json",
  "lazyCodeLoading": "requiredComponents"
}

根据你提供的 app.json 配置文件,我们可以将页面按功能模块进行分包,以减少主包的大小并提高加载速度。以下是一个分包的示例配置:

示例分包配置

json
{
  "pages": [
    "pages/home/home",
    "pages/login/login",
    "pages/plaza/plaza",
    "pages/me/me",
    "pages/me/settings/settings"
  ],
  "subpackages": [
    {
      "root": "subpackage-me",
      "pages": [
        "download/download",
        "want-to-watch/want-to-watch",
        "channel/channel",
        "devices/devices",
        "devices/device-detail/device-detail",
        "devices/bind-device/bind-device",
        "devices/device-format/device-format"
      ]
    },
    {
      "root": "subpackage-movies",
      "pages": ["search/search", "detail/detail", "result/index"]
    },
    {
      "root": "subpackage-channel",
      "pages": ["channel/channel"]
    },
    {
      "root": "subpackage-report",
      "pages": ["report/report", "report/form/form"]
    },
    {
      "root": "subpackage-agreement",
      "pages": ["agreement/agreement"]
    }
  ],
  "tabBar": {
    "custom": true,
    "list": [
      {
        "pagePath": "pages/home/home",
        "text": "首页"
      },
      {
        "pagePath": "pages/plaza/plaza",
        "text": "广场"
      },
      {
        "pagePath": "pages/me/me",
        "text": "我的"
      }
    ]
  },
  "window": {
    "backgroundTextStyle": "light",
    "navigationBarTextStyle": "black",
    "navigationBarTitleText": "圈子",
    "navigationBarBackgroundColor": "#ffffff"
  },
  "sitemapLocation": "sitemap.json",
  "lazyCodeLoading": "requiredComponents"
}

文件结构示例

确保你的项目文件夹结构如下:

project-root/
├─ pages/
│  ├─ home/
│  │  ├─ home.js
│  │  ├─ home.json
│  │  ├─ home.wxml
│  │  └─ home.wxss
│  ├─ login/
│  ├─ plaza/
│  ├─ me/
│  │  ├─ me.js
│  │  ├─ me.json
│  │  ├─ me.wxml
│  │  ├─ me.wxss
│  │  ├─ settings/
│  │  │  ├─ settings.js
│  │  │  ├─ settings.json
│  │  │  ├─ settings.wxml
│  │  │  └─ settings.wxss
├─ subpackage-me/
│  ├─ download/
│  ├─ want-to-watch/
│  ├─ channel/
│  ├─ devices/
│  │  ├─ devices.js
│  │  ├─ devices.json
│  │  ├─ devices.wxml
│  │  ├─ devices.wxss
│  │  ├─ device-detail/
│  │  ├─ bind-device/
│  │  ├─ device-format/
├─ subpackage-movies/
│  ├─ search/
│  ├─ detail/
│  ├─ result/
├─ subpackage-channel/
│  ├─ channel/
├─ subpackage-report/
│  ├─ report/
│  ├─ form/
├─ subpackage-agreement/
│  ├─ agreement/

调试与发布

在配置完成并确保文件结构正确后,可以通过微信开发者工具进行调试,查看分包是否正常加载。如果一切正常,则可以进行发布。

这样可以有效地减少主包的大小,并按需加载各个分包,提高小程序的加载速度和用户体验。

20. t-design 跳转页面后关闭 popup,但是还存在于页面上层

https://github.com/Tencent/tdesign-miniprogram/issues/2531#issuecomment-2174970786

21. 小程序体验版上线 - 页面不存在 - 扫码后显示页面不存在

问题:

alt text

原因:

alt text

解决方案:

  1. 进入微信小程序管理后台
  2. 首页 - 立即前往 alt text
  3. 修改页面路径
  4. / 修改成 /pages/home/homealt textalt text
  5. 重新生成二维码,扫码即可直接进入相关路由页面

22. 微信小程序自定义组件不要开启 shadow-root 可以吗

在微信小程序中,自定义组件默认会开启 shadow DOM(Shadow Root),这会使得组件的样式与外部样式隔离开来。如果你不想开启 shadow DOM,可以通过配置 options 来实现。

在自定义组件的 Component 构造器中,设置 options 属性的 styleIsolationapply-sharedshared 即可。这两种选项的区别在于:

  • apply-shared:组件样式会应用到外部样式,同时外部样式也会应用到组件。
  • shared:组件样式和外部样式会互相影响。

下面是一个示例:

javascript
Component({
  options: {
    styleIsolation: "apply-shared",
  },
  properties: {
    // 组件的属性列表
  },
  data: {
    // 组件的初始数据
  },
  methods: {
    // 组件的方法列表
  },
});

或者使用 shared

javascript
Component({
  options: {
    styleIsolation: "shared",
  },
  properties: {
    // 组件的属性列表
  },
  data: {
    // 组件的初始数据
  },
  methods: {
    // 组件的方法列表
  },
});

通过这种方式,你可以禁用 shadow DOM,让组件的样式与外部样式互相影响。

23. 微信小程序 scroll-view 如何滚动到顶部

在微信小程序中,如果你想让 scroll-view 组件滚动到顶部,可以使用 scrollTop 属性来实现。具体方法如下:

  1. 在 WXML 文件中设置 scroll-view 组件:

    xml
    <scroll-view
      scroll-y
      scroll-top="{{scrollTop}}"
      style="height: 300px;">
      <!-- 这里是滚动内容 -->
    </scroll-view>
  2. 在 JS 文件中定义 scrollTop 的值:

    javascript
    Page({
      data: {
        scrollTop: 0, // 初始值设为 0,即滚动到顶部
      },
    
      // 方法:滚动到顶部
      scrollToTop() {
        this.setData({
          scrollTop: 0, // 设置 scrollTop 为 0,实现滚动到顶部
        });
      },
    });
  3. 触发滚动到顶部的方法:

    你可以在页面的任何地方触发 scrollToTop 方法,例如在按钮点击事件中:

    xml
    <button bindtap="scrollToTop">滚动到顶部</button>
    javascript
    Page({
      data: {
        scrollTop: 0,
      },
    
      scrollToTop() {
        this.setData({
          scrollTop: 0,
        });
      },
    });

通过以上步骤,你可以在微信小程序中实现 scroll-view 组件滚动到顶部的效果。

24. 微信小程序切换 custom-tab-bar 的时候如果设置 scrollTop 怎么做

在使用 custom-tab-bar 的时候,如果你想设置 scrollTop,你需要在页面与自定义 tab bar 之间进行通信。具体步骤如下:

  1. 在页面中设置 scrollTop 属性:

    在需要使用 scroll-view 的页面中,定义一个 scrollTop 属性,并创建一个方法来更新该属性。

    javascript
    // 在页面的 JS 文件中
    Page({
      data: {
        scrollTop: 0,
      },
    
      onLoad() {
        // 获取 custom-tab-bar 实例
        const tabBar = this.getTabBar();
        if (tabBar) {
          // 监听自定义 tab bar 的事件
          tabBar.setScrollTopCallback = this.setScrollTop;
        }
      },
    
      setScrollTop(value) {
        this.setData({
          scrollTop: value,
        });
      },
    });
  2. 在页面的 WXML 文件中设置 scroll-view

    xml
    <scroll-view
      scroll-y
      scroll-top="{{scrollTop}}"
      style="height: 300px;">
      <!-- 滚动内容 -->
    </scroll-view>
  3. 在 custom-tab-bar 中设置按钮并触发事件:

    在自定义 tab bar 中创建一个按钮,点击按钮时触发滚动到顶部的事件。

    javascript
    // 在 custom-tab-bar 的 JS 文件中
    Component({
      data: {
        selected: 0,
        list: [
          {
            pagePath: "/pages/index/index",
            text: "首页",
          },
          {
            pagePath: "/pages/logs/logs",
            text: "日志",
          },
        ],
      },
      methods: {
        onLoad() {
          this.setScrollTopCallback = null;
        },
    
        switchTab(e) {
          const data = e.currentTarget.dataset;
          const url = data.path;
          wx.switchTab({ url });
          this.setData({
            selected: data.index,
          });
        },
    
        scrollToTop() {
          if (this.setScrollTopCallback) {
            this.setScrollTopCallback(0);
          }
        },
      },
    });
  4. 在 custom-tab-bar 的 WXML 文件中添加按钮:

    xml
    <view class="tab-bar">
      <button bindtap="scrollToTop">滚动到顶部</button>
      <!-- 其他 tab 项 -->
    </view>

通过以上步骤,你可以在使用 custom-tab-bar 的情况下,实现 scroll-view 滚动到顶部的功能。自定义 tab bar 中触发的 scrollToTop 方法会调用页面中的 setScrollTop 方法,从而更新 scrollTop 属性,达到滚动到顶部的效果。

25. 微信小程序如何不显示隐藏滚动条

参考 https://blog.csdn.net/T3165919332/article/details/132360138

xml
<mynavigation-bar pageName="device_detail" showLeftIcon="{{true}}" leftIconAutoBack="{{true}}" title="设备信息" />
<scroll-view scroll-top="{{scrollTop}}" class="scroll-detail-content" style="--statusBarHeight:{{statusBarHeight}}px;--navigationBarHeight:{{navigationBarHeight}}px;" type="custom" scroll-y show-scrollbar="{{false}}">
<!-- code ... -->
</scroll-view>
css
page {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  background-color: #f5f5f5;
  height: 100vh;
}

::-webkit-scrollbar {
  display: none;
  width: 0 !important;
  height: 0 !important;
  -webkit-appearance: none;
  background: transparent;
  color: transparent;
}

26. 微信小程序 button 按钮怎么去掉边框

如下图

alt text

这么做不生效

css
.avatar-wrapper {
  border: none;
}

解决办法,给.avatar-wrapper::after border none 即可:

html
<button
  class="avatar-wrapper"
  open-type="chooseAvatar"
  bind:chooseavatar="onChooseAvatar"
>
  <image class="default_avatar" src="{{avatar}}" mode="aspectFill" />
  <image
    class="avatar_edit"
    src="../../assets/me/avatar_edit.svg"
    mode="aspectFill"
  />
</button>
css
.avatar-wrapper::after {
  border: none;
}

最终效果

alt text

https://blog.csdn.net/qq_45067263/article/details/137583689

27. 微信小程序主包如何忽略指定的文件(主包尺寸(不包含插件)应小于 1.5M)

原因:微信小程序开发者工具 - 代码质量 提示“主包尺寸(不包含插件)应小于 1.5M”

alt text

解决问题:

下面的方式查看主包的大小,分析哪一个内容占用了大小,可以看到下面 主包的大小为 1.7MB

alt text

发现了一个代码中不应该出现的文件 image.png,看了一下这个是我 README.md 中引用的图片,但是这个图片没有在小程序中使用,而我把他放在了根目录

alt text

那么如何忽略 指定的文件呢? 微信小程序的 project.config.json 文件中的 packOptions.ignore 添加下面的代码,然后点击重新扫描,然后打开查看主包发现刚刚的文件已经从主包中移除

json
  "packOptions": {
    "ignore": [
      {
        "value": "image.png",
        "type": "file"
      }
    ],
    "include": []
  },

alt text

官方文档 https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html#packOptions

社区文档 https://blog.csdn.net/yzwlogo/article/details/131695302

根据上面的图片可以看到,我有两个 js 文件主包中没有使用,但是也打包在主包中了,提示了主包中不应存在未使用的JS文件

需要把提示的文件放到指定的分包中。

最终,改完之后,这里显示的全都是通过的

alt text