微信小程序自定义组件入门|从创建到实战(新手友好版)

0 阅读8分钟

微信小程序自定义组件入门|从创建到实战(新手友好版)

今天正式上手了微信小程序自定义组件的学习,从“什么是组件”到“怎么用组件”,踩了几个新手常见的小坑,也理清了核心逻辑。整理了一份保姆级笔记,适合和我一样刚入门的小伙伴,从零掌握自定义组件的基础用法,避免走弯路~

先明确核心:自定义组件是小程序中“可复用、可独立维护”的代码片段,比如页面中反复出现的搜索栏、商品卡片、导航栏,都可以封装成组件。好处很明显——减少重复代码、让页面结构更清晰,后期修改也更高效(改一处,所有引用的地方都生效)。

一、为什么要学自定义组件?(新手必懂)

刚开始写小程序,我习惯把所有代码都堆在页面的wxml、js里,直到写商品列表页时,发现搜索栏既要在首页用、又要在分类页用,复制粘贴两次不仅麻烦,后续改样式还要改两处,效率极低。

而自定义组件就能解决这个问题:将搜索栏封装成一个独立组件,首页、分类页直接“引用”即可,实现一次编写、多处复用,这也是小程序开发中“组件化思想”的核心——拆分复杂页面,降低维护成本

除此之外,组件还能实现“功能隔离”,组件内部的逻辑(比如输入事件、数据处理)不会影响页面其他部分,避免代码混乱,后期调试也更简单。

二、自定义组件的创建与目录结构(一步到位)

小程序的自定义组件,本质是由4个文件组成(和页面的文件结构一致,但配置不同),创建步骤很简单,新手直接跟着来:

1. 创建组件目录

在项目根目录下,新建一个components文件夹(用来统一存放所有自定义组件),然后在components里新建组件文件夹(比如我要做的搜索栏组件,文件夹名就叫search-bar)。

右键点击search-bar文件夹,选择“新建Component”,输入组件名(比如search-bar),小程序会自动生成4个文件:

  • search-bar.wxml:组件的布局结构(相当于组件的“骨架”);
  • search-bar.wxss:组件的样式(只作用于当前组件,不影响页面);
  • search-bar.js:组件的逻辑(数据、方法、生命周期);
  • search-bar.json:组件的配置(核心是声明“这是一个组件”)。

2. 组件核心配置(关键一步,不能漏)

组件和页面的核心区别,就在json配置文件里,必须在组件的json文件中声明component为true,否则小程序会把它当作页面解析,导致报错。

search-bar.json 正确配置(复制可用):

{
  "component": true, // 声明这是一个自定义组件(必写)
  "usingComponents": {} // 组件内部如果要引用其他组件,在这里配置(当前暂时为空)
}

三、组件的基础编写(以搜索栏为例,实战演示)

结合我今天写的搜索栏组件,给大家演示组件的wxml、wxss、js如何编写,贴合实际开发场景,新手可以直接复制修改。

1. 组件布局(wxml)

实现一个简单的搜索栏,包含输入框和搜索图标,结构和页面的wxml写法一致,可使用小程序原生组件(input、icon等):

<!-- search-bar.wxml -->
<view class="search-container">
  <view class="search-input">
    <uni-icons type="search" size="16" color="#999"></uni-icons>
  </view>
</view>

2. 组件样式(wxss)

组件的wxss样式默认只作用于当前组件(样式隔离),不用担心影响页面其他元素,写法和页面wxss一致:

/* search-bar.wxss */
.search-container {
  padding: 10rpx 20rpx;
  background: #f5f5f5;
}
.search-input {
  display: flex;
  align-items: center;
  background: #fff;
  border-radius: 30rpx;
  padding: 10rpx 20rpx;
}
.search-input input {
  flex: 1;
  font-size: 28rpx;
  margin-left: 10rpx;
  placeholder-color: #999;
}

3. 组件逻辑(js)

组件的js和页面的js写法有区别,核心是使用Component()构造器,里面包含data、methods、生命周期等配置。这里重点注意:组件的data必须是一个函数(和页面不同,页面data可以是对象),否则会报“dataOptions.call is not a function”错误(我今天踩的坑之一!)。

// search-bar.js
Component({
  // 组件的属性列表(用于接收父页面传递过来的数据)
  properties: {
    // 示例:接收父页面传递的默认提示文字
    placeholder: {
      type: String, // 数据类型
      value: "请输入搜索关键词" // 默认值
    }
  },

  // 组件的初始数据(必须是函数,返回对象)
  data: function() {
    return {
      searchVal: "", // 存储输入框的值
      isFocus: false // 控制输入框是否聚焦
    }
  },

  // 组件的方法列表(组件内部的事件处理)
  methods: {
    // 输入框输入事件
    handleInput(e) {
      // 注意:组件中input事件的参数e,值在e.detail.value中(新手易踩坑)
      this.setData({
        searchVal: e.detail.value
      })
      // 可以通过triggerEvent,将输入的值传递给父页面(下文会讲)
      this.triggerEvent("inputChange", this.data.searchVal)
    }
  }
})

四、组件的引用与通信(核心重点)

组件创建好后,不能直接使用,需要在要引用的页面中配置,然后才能在页面wxml中使用。另外,组件和页面之间的“数据传递”(通信)也是重点,主要分为两种:父传子、子传父。

1. 父页面引用组件(3步走)

假设我要在首页(pages/index/index)中引用search-bar组件,步骤如下:

第一步:在首页的json文件中,配置usingComponents,声明要引用的组件:

{
  "usingComponents": {
    // 键:组件在页面中使用的标签名(可自定义,建议和组件名一致)
    // 值:组件的路径(相对路径,从当前页面指向组件)
    "search-bar": "/components/search-bar/search-bar"
  }
}

第二步:在首页的wxml中,使用组件(标签名就是上面配置的“search-bar”):

<!-- index.wxml -->
<!-- 引用搜索栏组件,可传递placeholder属性(父传子) -->
<search-bar 
  placeholder="请搜索商品" 
  bind:inputChange="handleSearchInput"
></search-bar>

第三步:在首页的js中,处理组件传递过来的事件(子传父):

// index.js
Page({
  data: {},
  // 接收组件传递的输入值(事件名和组件中triggerEvent的第一个参数一致)
  handleSearchInput(val) {
    console.log("组件传递的搜索关键词:", val.detail)
    // 这里可以写搜索逻辑(比如调用接口获取搜索结果)
  }
})

2. 组件通信详解(新手必会)

组件和页面的通信,本质是“数据传递”,核心两种场景,结合上面的示例,讲得通俗一点:

  • 父传子:页面给组件传数据(比如上面的placeholder)。通过“组件标签的属性”传递,组件在properties中接收,就可以在组件内部使用这个数据;
  • 子传父:组件给页面传数据(比如上面的搜索关键词)。通过组件中的this.triggerEvent("事件名", 要传递的数据)触发事件,页面通过bind:事件名监听,就能拿到组件传递的数据。

补充:如果组件内部要修改父页面传递过来的数据,不能直接修改,需要通过子传父,让父页面修改后再传递回来(单向数据流,避免数据混乱)。

五、新手常见坑(我今天踩过的,帮你避坑)

结合今天的学习,整理了3个新手最容易踩的坑,遇到报错可以直接对应排查:

  1. 组件json文件未声明"component": true,导致小程序解析失败,报错“页面不存在”;
  2. 组件的data写成了对象(比如data: { searchVal: "" }),而非函数,报错“dataOptions.call is not a function”;
  3. 引用组件时,路径写错(比如多写/少写层级),或页面json中未配置usingComponents,导致组件不显示;
  4. input事件取值错误,直接写e.value(正确写法是e.detail.value),导致拿不到输入值。

六、学习总结与进阶方向

今天通过一个搜索栏组件,掌握了微信小程序自定义组件的核心流程:创建组件 → 配置组件 → 引用组件 → 组件通信。其实自定义组件的核心就是“复用”和“隔离”,把重复的功能封装起来,让代码更简洁、更易维护。

对于新手来说,重点掌握3点即可:

  • 组件的创建和配置(json文件的component: true必写);
  • 组件和页面的通信(父传子用properties,子传父用triggerEvent);
  • 避开data写法、路径配置、事件取值的常见坑。

后续进阶方向:组件的生命周期(比如created、attached)、组件的插槽(slot,让组件更灵活)、组件的样式隔离配置,这些都是实际开发中常用的知识点,后续学习再继续补充。

最后想说,小程序自定义组件不难,多动手写一个组件(比如搜索栏、商品卡片),踩一次坑,就能彻底掌握核心逻辑。新手不要怕报错,报错就是最好的学习机会,排查错误的过程,就是快速提升的过程~

如果这篇笔记对你有帮助,欢迎点赞收藏,一起学习小程序开发,打卡成长!🚀