微信小程序

203 阅读12分钟

微信小程序组件生命周期

  • onLoad, 生命周期函数--监听页面加载

  • onReady 生命周期函数--监听页面初次渲染完成

  • onShow 监听页面显示

  • onHide -监听页面隐藏

  • onUnload 监听页面卸载

  • onPullDownRefresh 监听用户下拉动作

  • onReachBottom 页面上拉触底事件的处理函数

  • onShareAppMessage 用户点击右上角分享

组件生命周期函数

image.png

image.png

组件所在页面的生命周期

image.png

一:组件

1:创建

image.png

2:引用

1):局部引用

image.png

2):全局引用

image.png

3:组件和页面区别

image.png

4:组件的样式隔离

1):默认的情况组件和页面的,组件与组件样式的是隔离的

2): app.wss 全局样式对组件中的样式 无效;所以必须用 @import "/app.wxss"引入

3):只有class选择器会有样式隔离效果,id选择器,属性选择器,标签选择器不受隔离效果(推荐用class)

4):针对性修改隔离效果方法 stylelsolation (2种方法):

image.png

image.png

5:组件中 事件处理和自定义事件 【为了代码分风格,自定义事件前面加__】

image.png

6:组件中properties 属性

image.png

7:组件中的 data和properties 的区别

image.png

image.png

8:组件中使用setData修改properties值

image.png

9:组件中数据监听器

image.png

1)变量监听

image.png

2)对象属性监听

image.png

案例:

image.png

3)监听所有属性(**通配符)

image.png

10:纯数字字段(不渲染到xwl)

image.png

1):使用规则

image.png

2):纯数字字段改变数据监听案例(上面对象属性监听案例改造)

image.png

11:组件中生命周期函数

image.png

1):主要三个生命周期函数 create 、attached、detached

image.png

12:lifetimes 节点(新版和旧版对比,推荐用新)

image.png

13:组件所在页面的生命周期

1):定义

image.png

2)pageLifetimes 节点

image.png

image.png

lifetimes【组件中的生命周期】 和 pageLifetimes【组件所在页面的生命周期】 区别

image.png

image.png

Component({
  data: {
    animationTimer: null,
    isPageShowing: true
  },
  // 1. 组件自身的生命周期
  lifetimes: {
    attached: function() {
      console.log('【组件】已挂载到页面');
      this.startAnimation(); // 页面初始是显示的,所以启动动画
    },
    detached: function() {
      console.log('【组件】被销毁');
      this.stopAnimation(); // 组件销毁时,彻底停止动画
    }
  },
  // 2. 组件所在页面的生命周期 (核心!)
  pageLifetimes: {
    show: function() {
      console.log('【页面】展示 - 组件感知到了');
     
    },
    hide: function() {
      console.log('【页面】隐藏 - 组件感知到了');

    },
    resize: function(size) {
      console.log('【页面】尺寸变化', size);
    }
  },
  methods: {
    
  }
})
案例:页面一进来随机默认一个颜色

image.png

14:组件中的插槽

1):定义

image.png

2)单个插槽

image.png

3)多个插槽

image.png

image.png

4)定义多个插槽

image.png

image.png

1. 基本用法

在微信小程序中,slot 的基本用法是在子组件中定义一个插槽,父组件可以在使用子组件时向插槽中传递内容。

子组件 (child-component.wxml):

<view class="container">
  <view>子组件的内容</view>
  <slot></slot> <!-- 这里是插槽,父组件的内容会插入到这里 -->
</view>

父组件 (parent-component.wxml):

<view>
  <child-component>
    <view>这是插入到子组件中的内容。</view>
  </child-component>
</view>

在这个例子中,<view>这是插入到子组件中的内容。</view> 会被插入到子组件的 <slot></slot> 位置。

2. 具名插槽 (Named Slots)

微信小程序也支持具名插槽,允许你在子组件中定义多个插槽,并通过名字来指定内容插入到哪个插槽中。

子组件 (child-component.wxml):

<view class="container">
  <view>子组件的内容</view>
  <slot name="header"></slot> <!-- 具名插槽 -->
  <slot></slot> <!-- 默认插槽 -->
  <slot name="footer"></slot> <!-- 具名插槽 -->
</view>

父组件 (parent-component.wxml):

<view>
  <child-component>
    <view slot="header">这是头部内容</view>
    <view>这是默认插槽的内容。</view>
    <view slot="footer">这是底部内容</view>
  </child-component>
</view>

在这个例子中,slot="header"slot="footer" 分别指定了内容插入到具名插槽 headerfooter 中,而没有指定 slot 的内容会插入到默认插槽中。

3. 作用域插槽 (Scoped Slots)

微信小程序目前不支持像 Vue 那样的作用域插槽(即子组件向父组件传递数据)。不过,你可以通过其他方式实现类似的功能,例如通过 propertiesevents 来传递数据。

4. 默认内容

你可以在 slot 中定义默认内容,当父组件没有提供内容时,默认内容会显示。

子组件 (child-component.wxml):

<view class="container">
  <view>子组件的内容</view>
  <slot>这是默认内容</slot>
</view>

父组件 (parent-component.wxml):

<view>
  <child-component></child-component> <!-- 显示默认内容 -->
  <child-component>
    <view>这是自定义内容</view>
  </child-component> <!-- 显示自定义内容 -->
</view>

15:子组件的之间通信

1):总结三种方法

image.png

2):性绑定(只能传普通数据给子组件)

image.png image.png

3):子组件向父组件传送数据 this.triggerEvent()

image.png

案例:

image.png

4):使用selectComponent获取组件实例

image.png

16:behaviors 各个组件共享代码

1):定义

image.png

2):方式

image.png

3):创建

image.png

4):导入

image.png

5):可用的节点

image.png

6):同名覆盖规则

image.png 参考: developers.weixin.qq.com/miniprogram…

image.png

在微信小程序中,behaviors 是一种用于在多个组件之间共享代码的机制。通过 behaviors,你可以将一些通用的逻辑、数据、方法等提取出来,然后在多个组件中复用。这样可以减少代码重复,提高代码的可维护性和可复用性。

1. 什么是 Behaviors?

behaviors 类似于面向对象编程中的“混入”(Mixin),它允许你将一些通用的功能封装到一个独立的模块中,然后在多个组件中引入和使用。每个 behavior 可以包含以下内容:

  • 数据 (data): 共享的数据字段。
  • 方法 (methods): 共享的方法。
  • 生命周期函数: 共享的生命周期逻辑。
  • 其他配置: 如 propertiesobservers 等。

2. 创建 Behavior

behavior 是一个普通的 JavaScript 文件,通常以 .js 为后缀。你可以通过 Behavior() 函数来定义一个 behavior

my-behavior.js:

module.exports = Behavior({
  data: {
    sharedData: '这是共享的数据'
  },
  methods: {
    sharedMethod() {
      console.log('这是共享的方法');
    }
  },
  created() {
    console.log('Behavior 创建了');
  },
  attached() {
    console.log('Behavior 附加了');
  }
});

在这个例子中,我们定义了一个 behavior,它包含了一些共享的数据和方法。

3. 在组件中使用 Behavior

在组件中使用 behavior 时,只需要在组件的 behaviors 字段中引入即可。

组件 (my-component.js):

const myBehavior = require('./my-behavior.js');

Component({
  behaviors: [myBehavior], // 引入 behavior
  data: {
    localData: '这是组件本地的数据'
  },
  methods: {
    localMethod() {
      console.log('这是组件本地的方法');
    }
  },
  created() {
    console.log('组件创建了');
  },
  attached() {
    console.log('组件附加了');
  }
});

在这个例子中,my-component 组件引入了 my-behavior,因此它可以访问 my-behavior 中定义的 sharedDatasharedMethod

4. Behavior 的生命周期

behavior 也有自己的生命周期函数,这些生命周期函数会在组件的生命周期中被调用。behavior 的生命周期函数与组件的生命周期函数是合并执行的,执行顺序如下:

  1. behaviorcreated
  2. 组件的 created
  3. behaviorattached
  4. 组件的 attached

5. Behavior 的冲突处理

如果 behavior 和组件中有同名的字段或方法,微信小程序会按照一定的规则进行合并:

  • 数据 (data): 同名的数据字段会进行合并,如果冲突,组件中的数据会覆盖 behavior 中的数据。
  • 方法 (methods): 同名的方法会进行合并,如果冲突,组件中的方法会覆盖 behavior 中的方法。
  • 生命周期函数: 同名的生命周期函数会合并执行,behavior 的生命周期函数先执行,组件的生命周期函数后执行。

6. 多个 Behavior 的合并

一个组件可以引入多个 behavior,这些 behavior 会按照数组顺序进行合并。如果多个 behavior 中有同名的字段或方法,后面的 behavior 会覆盖前面的 behavior

组件 (my-component.js):

const behaviorA = require('./behavior-a.js');
const behaviorB = require('./behavior-b.js');

Component({
  behaviors: [behaviorA, behaviorB], // 引入多个 behavior
  data: {
    localData: '这是组件本地的数据'
  },
  methods: {
    localMethod() {
      console.log('这是组件本地的方法');
    }
  }
});

7. 示例

假设我们有两个 behavior,分别用于处理用户信息和日志记录:

user-behavior.js:

module.exports = Behavior({
  data: {
    userInfo: null
  },
  methods: {
    getUserInfo() {
      wx.getUserInfo({
        success: (res) => {
          this.setData({
            userInfo: res.userInfo
          });
        }
      });
    }
  }
});

log-behavior.js:

module.exports = Behavior({
  methods: {
    log(message) {
      console.log(`[LOG]: ${message}`);
    }
  }
});

然后在组件中使用这两个 behavior

my-component.js:

const userBehavior = require('./user-behavior.js');
const logBehavior = require('./log-behavior.js');

Component({
  behaviors: [userBehavior, logBehavior],
  methods: {
    onLoad() {
      this.getUserInfo(); // 来自 userBehavior
      this.log('组件加载了'); // 来自 logBehavior
    }
  }
});

8. 总结

  • behaviors 是微信小程序中用于组件间代码复用的机制。
  • 你可以将通用的逻辑、数据、方法等提取到 behavior 中,然后在多个组件中共享使用。
  • behavior 的生命周期函数与组件的生命周期函数合并执行。
  • 如果 behavior 和组件中有同名的字段或方法,组件中的会覆盖 behavior 中的。
  • 一个组件可以引入多个 behavior,它们会按照数组顺序进行合并。

通过使用 behaviors,你可以更好地组织和管理微信小程序中的代码,减少重复代码,提高开发效率。

16:组件总结

image.png

小程序的优化

  1. 分包加载:将非核心功能拆分成子包,优化首屏加载。
  2. 分包预下载:在用户可能使用前,提前下载好分包。
  3. 图片优化:压缩、选对格式(WebP)、使用 CDN 和懒加载。
  4. 数据/文件缓存:合理使用本地存储,减少网络请求。
  5. 代码精简:删除无用代码,使用自定义组件。
  6. 高效 setData:避免频繁调用和大数据传输。
  7. 善用 WXS:处理高频交互,减少通信损耗。

1、分包加载和分包预下载

“首次只加载主包,分包按需加载+预加载”的策略

主包(1个)+分包(12)

  • 整个小程序所有分包大小不超过 20M
  • 单个分包/主包大小不能超过 2M

分包就是将一个小程序按照不同的维度(如功能、页面)划分成多个子包。启动时只下载主包,进入某个特定功能时再按需下载对应的分包

  • 主包:包含小程序启动页面(tabBar 页面)以及这些页面所需的所有相关资源(JS, WXML, WXSS, 图片等)。
  • 分包:包含与主包功能相对独立,且非 tabBar 页面的功能模块。

核心思想:按需加载

  1. 编译时分离:在开发者上传代码时,微信开发者工具会根据 app.json 中的 subpackagespreloadRule 配置, 将代码和资源明确地划分到主包和各个分包中,并生成对应的包信息。

  2. 运行时按需加载

    • 用户首次打开小程序,只会下载主包(通常 < 2M)。
    • 当用户通过导航(如点击按钮)要访问某个分包的页面时,小程序运行时环境会检查该页面所在的包是否已被下载。
    • 如果未下载,则会阻塞当前导航行为,显示一个全局的“正在加载...”提示,同时从 CDN 下载对应的分包。
    • 分包下载并注入完成后,才会正式跳转到目标页面,后续再访问该分包内的任何页面都无需重新加载。
3. 分包的配置

在 app.json 中进行配置:

{
  "pages": [
    "pages/index/index",
    "pages/logs/logs"
  ],
  "subpackages": [
    {
      "root": "packageA",
      "name": "packA", // 分包别名,用于分包预下载
      "pages": [
        "pages/cat/cat",
        "pages/dog/dog"
      ]
    },
    {
      "root": "packageB",
      "pages": [
        "pages/apple/apple",
        "pages/banana/banana"
      ]
    }
  ],
  "preloadRule": {
    "pages/index/index": {
      "network": "all",
      "packages": ["packageA"] // 当进入 pages/index/index 时,预下载 packageA
    }
  }
}
4. 分包预下载原理

为了进一步提升用户体验,避免用户在点击时等待分包下载,小程序提供了分包预下载机制。

  • 原理:在进入某个页面(通常是主包页面)后,在空闲时间 quietly 下载指定的分包。这样当用户真正需要进入该分包时,包已经准备就绪,可以实现秒开。
  • 配置:通过 app.json 的 preloadRule 字段配置。如上面的例子,当用户进入首页 (pages/index/index) 后,会自动在后台预下载 packageA

总结分包原理:通过将非核心功能代码从主包剥离,利用“首次只加载主包,分包按需加载+预加载”的策略,极大地优化了小程序的启动性能。

 2、图片优化

  • 压缩图片:使用工具(如 TinyPNG, Squoosh)对图片进行无损或有损压缩。

  • 选择合适的格式

    • WebP:同等质量下体积比 PNG/JPG 小很多。小程序已支持,但需考虑低版本兼容性(可做兼容判断,不支持则 fallback 到 JPG)。
    • SVG:适用于图标、LOGO 等矢量图。
  • 使用 CDN 和合适尺寸

    • 不要将大量高分辨率图片打包到代码包里,应上传至 CDN。
    • 根据显示区域的大小,从 CDN 请求对应尺寸的图片。例如,一个需要显示 200x200 像素的头像,就不要请求 1000x1000 的原图。
  • 懒加载:使用小程序原生的 lazy-load 属性,让屏幕外的图片在需要时才加载。

<image src="{{imgUrl}}" lazy-load mode="widthFix"></image>

3. 缓存策略

合理利用缓存可以减少网络请求,提升二次访问速度。

  • 数据缓存 (wx.setStoragewx.getStorage):

    • 缓存不常变化但频繁使用的数据,如用户信息、城市列表、配置信息等。
    • 为缓存设置合理的过期时间,或提供手动刷新机制。
  • 文件缓存 (wx.saveFilewx.getFileSystemManager):

    • 对于较大的静态文件(如 PDF、视频),可以下载到本地缓存,避免重复下载。
  • 请求缓存

    • 对于相同的 API 请求,可以在内存中做一个短期缓存(例如 5 秒),避免短时间内重复请求。

3. 代码层面的优化

清理无用代码和资源:定期检查并删除未使用的 JS 函数、WXML 组件、WXSS 样式和图片。

  • 减少 setData 的调用频率和数据量

    • setData 是视图层和逻辑层的通信,频繁调用或传输大量数据(如巨大的数组)会引起性能问题。
    • 只 set 发生变化的数据,而不是整个 data 对象。
    • 列表进行分页避免一次性 set 大量数据。
  • 使用自定义组件:将复杂的页面拆分成独立的自定义组件,可以实现更好的代码复用和隔离,组件的更新不会影响页面其他部分。

  • 使用 WXS 处理交互:对于需要高频交互的场景(如滚动、触摸),使用 WXS 可以在视图层直接处理,避免逻辑层和视图层的频繁通信带来的延迟。