小程序组件化进阶:从复用到通信的完整指南DAY04

当小程序页面越来越复杂时,组件化开发是提升代码复用性、可维护性的核心手段。这篇文章将带你掌握小程序自定义组件的创建、样式、数据监听、父子通信及 behaviors 复用,让你写出更优雅、高效的小程序代码。

一、创建并引用自定义组件

自定义组件是小程序的「可复用模块」,我们先从最基础的创建与引用开始。

1. 创建组件

在项目根目录新建 components 文件夹,每个组件都是一个独立文件夹,包含 .js/.json/.wxml/.wxss 四个文件:

json 复制代码
// components/custom-btn/custom-btn.js
Component({
  // 组件的属性、数据、方法等
})

2. 引用组件

引用分为全局引用和局部引用,通过 usingComponents 配置实现:
局部引用(推荐,仅当前页面可用)

在目标页面的 .json 中配置:

json 复制代码
{
  "usingComponents": {
    "custom-btn": "/components/custom-btn/custom-btn" // 键名是组件标签名,值是组件路径
  }
}

在页面 .wxml 中直接使用:

wxml 复制代码
<custom-btn></custom-btn>

全局引用(所有页面可用)

app.json 中配置,一次配置全项目生效:

json 复制代码
{
  "usingComponents": {
    "custom-btn": "/components/custom-btn/custom-btn"
  }
}

二、组件样式隔离:控制样式影响范围

小程序组件默认样式隔离,通过 styleIsolation 选项修改隔离规则,避免样式污染。

1. 三种隔离模式

在组件 .jsoptions 中配置:

js 复制代码
Component({
  options: {
    styleIsolation: 'isolated' // 默认值,完全隔离
    // styleIsolation: 'apply-shared' // 组件可继承页面/全局样式,自身样式不向外影响
    // styleIsolation: 'shared' // 组件与页面/全局样式互相影响(不推荐,易冲突)
  }
})

isolated:组件样式完全独立,不受外部影响,也不影响外部。通用组件、基础组件
apply-shared: 组件可继承外部样式,但自身样式不泄露。业务组件,需复用全局主题
shared: 组件与外部样式互相渗透。特殊场景,谨慎使用

三、数据监听器:监听数据变化并响应

通过 observers 监听组件数据 / 属性变化,实现数据驱动的逻辑响应。

1. 基础用法

js 复制代码
Component({
  properties: {
    count: Number
  },
  data: {
    total: 0
  },
  observers: {
    // 监听 count 属性变化,自动更新 total
    'count': function(newVal, oldVal) {
      this.setData({
        total: newVal * 2
      })
    },
    // 监听多个字段变化
    'count, total': function(newCount, newTotal) {
      console.log('count或total变化了', newCount, newTotal);
    }
  }
})

2. 监听对象 / 数组

支持监听对象属性或数组元素:

js 复制代码
observers: {
  'user.name': function(newName) {
    console.log('用户名变为:', newName);
  },
  'list[0].title': function(newTitle) {
    console.log('列表第一项标题变为:', newTitle);
  }
}

四、纯数据字段:优化性能的小技巧

纯数据字段是不参与界面渲染的字段,通过 pureDataPattern 配置,减少不必要的 setData 性能消耗。

1. 配置与使用

js 复制代码
Component({
  options: {
    pureDataPattern: /^_/ // 约定以下划线 _ 开头的字段为纯数据字段
  },
  data: {
    _timer: null, // 纯数据字段,不渲染到页面
    count: 0 // 普通字段,参与渲染
  },
  methods: {
    startTimer() {
      this.data._timer = setInterval(() => {
        this.setData({ count: this.data.count + 1 })
      }, 1000)
    }
  }
})

优势:纯数据字段修改时不会触发页面重渲染,适合存储定时器、临时状态等非 UI 数据。

五、父子组件通信:3 种核心方式

组件间通信是组件化的核心,小程序提供了三种父子通信方式,覆盖不同场景。

1. 方式一:属性绑定(父 → 子,单向传递)

父组件通过属性向子组件传递数据,子组件通过 properties 接收:

wxml 复制代码
<!-- 父页面.wxml -->
<custom-btn title="点击我" count="{{count}}"></custom-btn>
js 复制代码
// 子组件.js
Component({
  properties: {
    title: String,
    count: Number
  }
})

2. 方式二:事件绑定(子 → 父,事件通知)

子组件通过 triggerEvent 触发自定义事件,父组件通过 bind: 监听:

js 复制代码
// 子组件.js
Component({
  methods: {
    handleClick() {
      // 触发事件,向父组件传递数据
      this.triggerEvent('myevent', { count: this.properties.count })
    }
  }
})
wxml 复制代码
<!-- 父页面.wxml -->
<custom-btn bind:myevent="onMyEvent"></custom-btn>
js 复制代码
// 父页面.js
Page({
  onMyEvent(e) {
    console.log('子组件传递的数据:', e.detail); // { count: ... }
  }
})

3. 方式三:this.selectComponent()(父 → 子,直接调用)

父组件通过选择器获取子组件实例,直接调用子组件方法或访问数据:

wxml 复制代码
<!-- 父页面.wxml -->
<custom-btn class="my-btn" id="btn"></custom-btn>
js 复制代码
// 父页面.js
Page({
  onLoad() {
    // 通过 id 或 class 选择器获取子组件实例
    const child = this.selectComponent('#btn')
    // 直接调用子组件方法
    child.handleClick()
    // 直接访问子组件数据
    console.log(child.properties.count)
  }
})

六、behaviors:复用组件逻辑的利器

behaviors 是小程序的「代码复用模块」,类似 Mixin,可将多个组件的公共逻辑抽离复用。

1. 定义 behavior

新建 behaviors 文件夹,创建 behavior 文件:

js 复制代码
// behaviors/common.js
module.exports = Behavior({
  // 公共数据
  data: {
    commonData: '我是公共数据'
  },
  // 公共方法
  methods: {
    commonMethod() {
      console.log('我是公共方法')
    }
  },
  // 公共生命周期
  created() {
    console.log('behavior created')
  }
})

2. 组件中引入 behavior

js 复制代码
// 子组件.js
const commonBehavior = require('../../behaviors/common.js')
Component({
  behaviors: [commonBehavior], // 引入behavior
  methods: {
    handleClick() {
      this.commonMethod() // 直接调用behavior中的方法
      console.log(this.data.commonData) // 直接访问behavior中的数据
    }
  }
})

特性:多个 behaviors 或组件与 behaviors 之间,同名数据 / 方法会按优先级覆盖,生命周期会依次执行。

相关推荐
读忆2 小时前
你是否用过Tailwind CSS?你是在什么情况下使用的呢?
前端·css·经验分享·笔记·taiiwindcss
是Winky啊2 小时前
【逆向+爬虫】获取小程序信息
小程序
阿珊和她的猫2 小时前
探秘小程序:为何拿不到 DOM 相关 API
前端·小程序
灵机一物2 小时前
灵机一物AI智能电商小程序(已上线)-LangGraph落地电商购物Agent:搜索反馈回路从工程实践到产品化落地
人工智能·小程序
FlyWIHTSKY2 小时前
Vue 3 onMounted 中控制同步与异步执行策略
前端·javascript·vue.js
蜗牛攻城狮2 小时前
【Vue3实战】El-Table实现“超过3行省略,悬停显示全文”的完美方案(附性能优化)
前端·vue.js·性能优化·element-plus
孙12~2 小时前
前端vue3+vite,后端SpringBoot+MySQL
前端·html·学习方法
隔壁小邓2 小时前
vue的组件化的理解之单独拆分的组件&组件的封装
前端·javascript·vue.js
困惑阿三2 小时前
全栈部署排雷手册:从 405 报错到飞书推送成功
服务器·前端·后端·nginx·阿里云·node.js·飞书