移动端-重新学习-20260407

4 阅读14分钟

移动端

一、小程序基础

1. 小程序概述与特点

问题:小程序的作用是什么?小程序的特点是什么?小程序与 H5 的区别是什么?小程序与 App 的区别是什么?小程序的应用场景有哪些?

答案

小程序定义:小程序是一种运行在特定平台(如微信、支付宝、百度等)内部的轻量级应用程序,无需下载安装即可使用,实现了"触手可及、用完即走"的理念。

小程序的作用

  1. 轻量化服务:提供核心功能,无需完整App的复杂功能
  2. 降低获取成本:用户无需下载安装,扫码或搜索即可使用
  3. 提升转化率:缩短用户路径,提高业务转化效率
  4. 平台生态整合:与平台能力深度整合(支付、分享、社交等)
  5. 跨平台一致性:在不同设备上提供一致体验

小程序的特点

  • 无需安装:直接在平台内运行,不占用设备存储
  • 即用即走:使用后不留痕迹,可随时再次访问
  • 开发成本低:相比原生App,开发和维护成本更低
  • 跨平台:一次开发,多平台运行(理论上)
  • 体验接近原生:使用平台提供的组件和API,体验流畅
  • 获客门槛低:可通过扫码、搜索、分享等快速获客
  • 审核快速:相比App Store,审核周期更短

小程序 vs H5 对比表

对比项小程序H5网页
运行环境平台提供的沙箱环境浏览器环境
技术栈WXML、WXSS、JS(平台特定)HTML、CSS、JavaScript(标准)
性能体验接近原生,加载快依赖网络,性能较差
系统权限可调用部分系统能力(需授权)能力受限,依赖浏览器API
发布方式平台审核后发布直接部署到服务器
更新机制版本更新需审核实时更新,无需审核
存储能力本地存储(平台提供)Cookie、LocalStorage等
分享能力深度整合平台分享依赖浏览器的分享能力
入口场景扫码、搜索、分享、历史列表等URL链接、二维码等
网络请求平台封装的安全请求标准HTTP/HTTPS请求

小程序 vs App 对比表

对比项小程序原生App
安装方式无需安装,即用即走需要下载安装包
占用空间无需下载,缓存小下载安装,占用存储空间
开发成本较低(一套代码多平台)较高(需多平台开发)
开发周期较短较长
性能体验接近原生,但有限制最优,可充分调用系统能力
功能完整性受限(平台限制)完整,可调用所有系统API
用户粘性较低(用完即走)较高(占桌面入口)
推送能力受限(模板消息)完整推送(可实时推送)
审核机制平台审核(较快)应用商店审核(较严)
更新方式后台更新,用户无感知需要用户主动更新

小程序应用场景

  1. 工具类:计算器、翻译、天气查询等轻量工具
  2. 电商类:商品展示、购物车、订单管理
  3. 服务类:预约、点餐、票务预订
  4. 资讯类:新闻阅读、内容聚合
  5. 社交类:社区、论坛、小游戏
  6. 企业服务:CRM、内部办公、数据展示
  7. 生活服务:缴费、出行、政务办理

微信小程序特点补充

  • 微信生态整合:与微信支付、微信登录、微信分享深度整合
  • 社交传播能力强:可通过微信群、朋友圈快速传播
  • 用户基数大:依托微信10亿+用户
  • 开发工具完善:官方提供完整的开发工具链
  • 文档和社区成熟:官方文档齐全,社区活跃

二、微信小程序架构

2. 小程序框架与目录结构

问题:什么是微信小程序?微信小程序的目录结构是什么?微信小程序的配置文件有哪些?app.json、app.js、app.wxss 的配置是什么?小程序的框架是什么?小程序的 MVVM 模式是什么?

答案

微信小程序定义:微信小程序是运行在微信内部的应用,基于微信提供的框架和API进行开发,具有独立的运行环境和沙盒机制。

微信小程序目录结构

project-name/
├── pages/                    # 页面目录
│   ├── index/               # 首页
│   │   ├── index.js         # 页面逻辑
│   │   ├── index.json       # 页面配置
│   │   ├── index.wxml       # 页面结构
│   │   └── index.wxss       # 页面样式
│   └── logs/                # 日志页
├── utils/                   # 工具类目录
│   └── util.js             # 工具函数
├── app.js                  # 应用逻辑
├── app.json                # 应用配置
├── app.wxss                # 应用全局样式
├── project.config.json     # 项目配置
└── sitemap.json            # 站点地图配置

配置文件详解

1. app.json(应用配置)

{
  "pages": [
    "pages/index/index",
    "pages/logs/logs",
    "pages/user/user"
  ],
  "window": {
    "navigationBarTitleText": "我的小程序",
    "navigationBarBackgroundColor": "#ffffff",
    "navigationBarTextStyle": "black",
    "backgroundColor": "#f8f8f8",
    "backgroundTextStyle": "light",
    "enablePullDownRefresh": true
  },
  "tabBar": {
    "list": [
      {
        "pagePath": "pages/index/index",
        "text": "首页",
        "iconPath": "images/home.png",
        "selectedIconPath": "images/home-active.png"
      },
      {
        "pagePath": "pages/user/user",
        "text": "我的",
        "iconPath": "images/user.png",
        "selectedIconPath": "images/user-active.png"
      }
    ],
    "color": "#999999",
    "selectedColor": "#FF0000",
    "backgroundColor": "#ffffff",
    "borderStyle": "black"
  },
  "networkTimeout": {
    "request": 10000,
    "connectSocket": 10000,
    "uploadFile": 10000,
    "downloadFile": 10000
  },
  "debug": true,
  "functionalPages": true,
  "subpackages": [
    {
      "root": "packageA",
      "pages": [
        "pages/cat/cat",
        "pages/dog/dog"
      ]
    }
  ],
  "preloadRule": {
    "pages/index/index": {
      "network": "all",
      "packages": ["packageA"]
    }
  }
}

app.json 配置字段说明

  • pages:页面路径列表,第一个页面为小程序的首页
  • window:全局窗口配置(导航栏、背景色等)
  • tabBar:底部/顶部tab栏配置
  • networkTimeout:网络请求超时时间
  • debug:是否开启调试模式
  • functionalPages:是否启用功能页
  • subpackages:分包配置,用于代码分包加载
  • preloadRule:分包预下载规则

2. app.js(应用逻辑)

// app.js
App({
  // 小程序初始化时执行,全局只触发一次
  onLaunch(options) {
    console.log('小程序初始化', options);
    // 获取用户信息
    wx.getUserInfo({
      success: res => {
        this.globalData.userInfo = res.userInfo;
      }
    });
    
    // 检查更新
    if (wx.canIUse('getUpdateManager')) {
      const updateManager = wx.getUpdateManager();
      updateManager.onCheckForUpdate(res => {
        if (res.hasUpdate) {
          console.log('检测到新版本');
        }
      });
    }
  },
  
  // 小程序显示时执行(从后台进入前台)
  onShow(options) {
    console.log('小程序显示', options);
  },
  
  // 小程序隐藏时执行(从前台进入后台)
  onHide() {
    console.log('小程序隐藏');
  },
  
  // 小程序发生脚本错误时执行
  onError(error) {
    console.error('小程序错误', error);
  },
  
  // 全局数据
  globalData: {
    userInfo: null,
    token: '',
    appVersion: '1.0.0'
  },
  
  // 自定义全局方法
  login() {
    return new Promise((resolve, reject) => {
      wx.login({
        success: res => {
          if (res.code) {
            // 发送code到服务器换取openid和session_key
            resolve(res.code);
          } else {
            reject(res.errMsg);
          }
        },
        fail: reject
      });
    });
  }
});

3. app.wxss(全局样式)

/* app.wxss - 全局样式 */
page {
  font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', sans-serif;
  font-size: 32rpx;
  color: #333;
  background-color: #f8f8f8;
}

/* 文本样式 */
.text-primary {
  color: #576b95;
}

.text-success {
  color: #09bb07;
}

.text-warning {
  color: #e64340;
}

/* 布局样式 */
.flex-row {
  display: flex;
  flex-direction: row;
}

.flex-column {
  display: flex;
  flex-direction: column;
}

.flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

/* 边距样式 */
.mt-10 {
  margin-top: 10rpx;
}

.mb-10 {
  margin-bottom: 10rpx;
}

.ml-10 {
  margin-left: 10rpx;
}

.mr-10 {
  margin-right: 10rpx;
}

/* 按钮样式 */
.btn {
  padding: 20rpx 40rpx;
  border-radius: 8rpx;
  text-align: center;
  font-size: 32rpx;
}

.btn-primary {
  background-color: #07c160;
  color: #fff;
}

.btn-disabled {
  background-color: #cccccc;
  color: #ffffff;
}

小程序框架: 微信小程序采用 MVVM(Model-View-ViewModel) 架构模式:

MVVM 组件关系

  • Model(模型):数据层,对应小程序中的data对象和服务器数据
  • View(视图):界面层,对应WXML模板,负责UI展示
  • ViewModel(视图模型):逻辑层,对应小程序Page对象,负责数据绑定和事件处理

MVVM 数据流

  1. 数据绑定:View通过数据绑定显示Model中的数据
  2. DOM监听:View中的用户操作触发事件,通知ViewModel
  3. 数据更新:ViewModel更新Model,Model的变化自动同步到View

小程序 MVVM 实现

// page.js - ViewModel
Page({
  // Model数据
  data: {
    message: 'Hello World',
    items: ['Apple', 'Banana', 'Orange'],
    user: {
      name: '张三',
      age: 25
    },
    count: 0
  },
  
  // 事件处理函数
  onTapButton() {
    // 更新Model数据
    this.setData({
      count: this.data.count + 1
    });
  },
  
  onInputChange(e) {
    this.setData({
      message: e.detail.value
    });
  }
});
<!-- page.wxml - View -->
<view class="container">
  <!-- 数据绑定 -->
  <text>{{message}}</text>
  
  <!-- 列表渲染 -->
  <view wx:for="{{items}}" wx:key="index">
    {{index + 1}}. {{item}}
  </view>
  
  <!-- 条件渲染 -->
  <view wx:if="{{count > 0}}">
    点击次数:{{count}}
  </view>
  
  <!-- 事件绑定 -->
  <button bindtap="onTapButton">点击我</button>
  
  <!-- 双向绑定(基础库2.9.3+) -->
  <input model:value="{{message}}" />
</view>

小程序框架核心特性

  1. 数据驱动:数据变化自动更新视图
  2. 组件化:内置丰富组件和自定义组件支持
  3. 模块化:支持CommonJS模块规范
  4. 事件系统:tap、input、scroll等事件处理
  5. 生命周期:页面和应用级别的生命周期管理
  6. 路由系统:页面栈管理和导航控制

三、小程序组件

3. 小程序组件与使用

问题:小程序的组件有哪些?视图容器组件有哪些?view、scroll-view、swiper组件的使用?基础内容组件有哪些?text、rich-text组件的使用?表单组件有哪些?button、input组件的使用?媒体组件有哪些?image、video组件的使用?如何创建自定义组件?组件的通信方法有哪些?

答案

小程序组件分类

  • 视图容器组件:view、scroll-view、swiper、movable-view等
  • 基础内容组件:text、rich-text、icon、progress等
  • 表单组件:button、checkbox、radio、input、textarea等
  • 媒体组件:image、video、audio、camera等
  • 地图组件:map
  • 画布组件:canvas
  • 导航组件:navigator
  • 开放能力组件:open-data、web-view等

1. 视图容器组件

view(视图容器)

  • 基本布局容器,类似于HTML中的div
  • 支持flex布局、hover效果、点击事件等
<!-- 基础使用 -->
<view class="container">
  <view class="item" hover-class="hover-style" bindtap="onItemTap">
    点击我有hover效果
  </view>
</view>
/* wxss */
.container {
  display: flex;
  flex-direction: column;
}

.item {
  padding: 20rpx;
  margin: 10rpx;
  background-color: #f0f0f0;
}

.hover-style {
  background-color: #e0e0e0;
}

scroll-view(可滚动视图)

  • 可滚动的视图区域,支持横向或纵向滚动
  • 常用属性:scroll-x、scroll-y、scroll-top、bindscroll等
<!-- 纵向滚动 -->
<scroll-view 
  scroll-y 
  style="height: 500rpx;"
  bindscroll="onScroll"
  scroll-top="{{scrollTop}}">
  <view wx:for="{{100}}" wx:key="index" style="height: 100rpx;">
    第{{index + 1}}项
  </view>
</scroll-view>

<!-- 横向滚动 -->
<scroll-view scroll-x style="white-space: nowrap;">
  <view wx:for="{{10}}" wx:key="index" style="display: inline-block; width: 200rpx;">
    横向项{{index + 1}}
  </view>
</scroll-view>

swiper(滑块视图容器)

  • 轮播图组件,支持自动播放、无限循环、指示点等
  • 常用属性:autoplay、interval、duration、indicator-dots等
<swiper 
  autoplay="{{true}}"
  interval="{{3000}}"
  duration="{{500}}"
  indicator-dots="{{true}}"
  indicator-color="rgba(0,0,0,.3)"
  indicator-active-color="#000">
  <swiper-item wx:for="{{banners}}" wx:key="index">
    <image 
      src="{{item.imageUrl}}" 
      mode="aspectFill"
      bindtap="onBannerTap"
      data-id="{{item.id}}"
      style="width: 100%; height: 100%;" />
  </swiper-item>
</swiper>

2. 基础内容组件

text(文本)

  • 文本组件,支持长按选择、复制、空格处理等
  • 常用属性:selectable、space、decode、user-select等
<view>
  <!-- 基础文本 -->
  <text>普通文本</text>
  
  <!-- 可选中文本 -->
  <text selectable="{{true}}">可选中文本</text>
  
  <!-- 处理空格 -->
  <text space="ensp">文本 空格</text>
  
  <!-- HTML实体解码 -->
  <text decode="{{true}}">&lt;div&gt;HTML实体&lt;/div&gt;</text>
  
  <!-- 内嵌样式 -->
  <text class="text-class" style="color: red;">样式文本</text>
  
  <!-- 嵌套文本 -->
  <text>
    嵌套
    <text style="font-weight: bold;">加粗</text>
    文本
  </text>
</view>

rich-text(富文本)

  • 支持HTML节点和属性的富文本组件
  • 通过nodes属性传入节点数组或HTML字符串
<rich-text nodes="{{htmlNodes}}" />
Page({
  data: {
    // 节点数组格式
    htmlNodes: [
      {
        name: 'div',
        attrs: { class: 'wrapper' },
        children: [
          {
            name: 'h1',
            attrs: { style: 'color: red;' },
            children: [{ type: 'text', text: '标题' }]
          },
          {
            name: 'p',
            children: [
              { type: 'text', text: '段落内容' },
              {
                name: 'span',
                attrs: { style: 'font-weight: bold;' },
                children: [{ type: 'text', text: '加粗文本' }]
              }
            ]
          },
          {
            name: 'img',
            attrs: {
              src: 'https://example.com/image.jpg',
              style: 'width: 100px; height: 100px;'
            }
          }
        ]
      }
    ],
    
    // HTML字符串格式(基础库2.4.4+)
    htmlString: '<div class="wrapper"><h1 style="color: red;">标题</h1><p>段落内容<span style="font-weight: bold;">加粗文本</span></p><img src="https://example.com/image.jpg" style="width: 100px; height: 100px;" /></div>'
  }
});

3. 表单组件

button(按钮)

  • 按钮组件,支持多种类型和开放能力
  • 常用属性:type、size、plain、loading、form-type等
<view>
  <!-- 主要按钮 -->
  <button type="primary" bindtap="onPrimaryTap">主要按钮</button>
  
  <!-- 次要按钮 -->
  <button type="default" bindtap="onDefaultTap">默认按钮</button>
  
  <!-- 警告按钮 -->
  <button type="warn" bindtap="onWarnTap">警告按钮</button>
  
  <!-- 禁用状态 -->
  <button disabled="{{true}}">禁用按钮</button>
  
  <!-- 加载状态 -->
  <button loading="{{isLoading}}" bindtap="onLoadingTap">加载按钮</button>
  
  <!-- 镂空按钮 -->
  <button plain="{{true}}" type="primary">镂空按钮</button>
  
  <!-- 表单提交按钮 -->
  <form bindsubmit="onFormSubmit">
    <input name="username" placeholder="请输入用户名" />
    <button form-type="submit">提交</button>
    <button form-type="reset">重置</button>
  </form>
  
  <!-- 开放能力(获取用户信息) -->
  <button open-type="getUserInfo" bindgetuserinfo="onGetUserInfo">
    获取用户信息
  </button>
  
  <!-- 分享 -->
  <button open-type="share" bindtap="onShare">分享</button>
</view>

input(输入框)

  • 单行输入框组件,支持多种输入类型
  • 常用属性:value、type、password、placeholder、focus、bindinput等
<view>
  <!-- 文本输入 -->
  <input 
    value="{{username}}"
    placeholder="请输入用户名"
    bindinput="onUsernameInput"
    maxlength="20" />
  
  <!-- 数字输入 -->
  <input 
    type="number"
    value="{{age}}"
    placeholder="请输入年龄"
    bindinput="onAgeInput" />
  
  <!-- 密码输入 -->
  <input 
    type="password"
    value="{{password}}"
    placeholder="请输入密码"
    password="{{true}}"
    bindinput="onPasswordInput" />
  
  <!-- 身份证输入 -->
  <input 
    type="idcard"
    placeholder="请输入身份证号"
    bindinput="onIdCardInput" />
  
  <!-- 数字键盘输入 -->
  <input 
    type="digit"
    placeholder="请输入金额"
    bindinput="onDigitInput" />
  
  <!-- 获取焦点 -->
  <input 
    focus="{{isFocus}}"
    placeholder="自动获取焦点"
    bindfocus="onFocus"
    bindblur="onBlur" />
  
  <!-- 带清除按钮 -->
  <input 
    value="{{searchText}}"
    placeholder="搜索..."
    confirm-type="search"
    bindconfirm="onSearch"
    bindinput="onSearchInput" />
</view>
Page({
  data: {
    username: '',
    age: '',
    password: '',
    searchText: '',
    isFocus: false
  },
  
  onUsernameInput(e) {
    this.setData({ username: e.detail.value });
  },
  
  onAgeInput(e) {
    this.setData({ age: e.detail.value });
  },
  
  onPasswordInput(e) {
    this.setData({ password: e.detail.value });
  },
  
  onSearchInput(e) {
    this.setData({ searchText: e.detail.value });
  },
  
  onSearch(e) {
    console.log('搜索:', this.data.searchText);
    // 执行搜索操作
  },
  
  onFocus() {
    console.log('输入框获取焦点');
  },
  
  onBlur() {
    console.log('输入框失去焦点');
  }
});

4. 媒体组件

image(图片)

  • 图片组件,支持懒加载、错误处理、多种展示模式
  • 常用属性:src、mode、lazy-load、bindload、binderror等
<view>
  <!-- 基础图片 -->
  <image src="{{imageUrl}}" />
  
  <!-- 指定展示模式 -->
  <image 
    src="{{avatarUrl}}"
    mode="aspectFill"
    style="width: 200rpx; height: 200rpx; border-radius: 50%;" />
  
  <!-- 懒加载 -->
  <image 
    src="{{bannerUrl}}"
    mode="widthFix"
    lazy-load="{{true}}"
    bindload="onImageLoad"
    binderror="onImageError" />
  
  <!-- 占位图 -->
  <image 
    class="product-image"
    src="{{product.imageUrl || '/images/placeholder.png'}}"
    mode="aspectFit" />
  
  <!-- 图片预览 -->
  <image 
    src="{{previewImage}}"
    mode="aspectFit"
    bindtap="previewImage"
    data-src="{{previewImage}}" />
</view>

图片 mode 属性详解

模式值说明特点
scaleToFill缩放模式,不保持纵横比填充整个image元素
aspectFit缩放模式,保持纵横比完整显示图片,可能留白
aspectFill缩放模式,保持纵横比填充整个元素,可能裁剪
widthFix宽度不变,高度自适应高度按原图比例计算
top不缩放,顶部对齐
bottom不缩放,底部对齐
center不缩放,居中
left不缩放,左对齐
right不缩放,右对齐
top left不缩放,左上角对齐
top right不缩放,右上角对齐
bottom left不缩放,左下角对齐
bottom right不缩放,右下角对齐

video(视频)

  • 视频播放组件,支持弹幕、控制栏、全屏等
  • 常用属性:src、controls、autoplay、loop、bindplay、bindpause等
<view>
  <!-- 基础视频播放 -->
  <video 
    src="{{videoUrl}}"
    controls="{{true}}"
    autoplay="{{false}}"
    loop="{{false}}"
    muted="{{false}}"
    bindplay="onVideoPlay"
    bindpause="onVideoPause"
    bindended="onVideoEnded"
    style="width: 100%; height: 400rpx;" />
  
  <!-- 自定义视频控制 -->
  <video 
    id="myVideo"
    src="{{videoUrl}}"
    controls="{{false}}"
    bindtimeupdate="onTimeUpdate"
    style="width: 100%; height: 400rpx;" />
  
  <view class="video-controls">
    <button bindtap="playVideo">播放</button>
    <button bindtap="pauseVideo">暂停</button>
    <button bindtap="seekVideo">跳转到30秒</button>
    <button bindtap="requestFullScreen">全屏</button>
  </view>
</view>
Page({
  onReady() {
    this.videoContext = wx.createVideoContext('myVideo');
  },
  
  playVideo() {
    this.videoContext.play();
  },
  
  pauseVideo() {
    this.videoContext.pause();
  },
  
  seekVideo() {
    this.videoContext.seek(30); // 跳转到30秒
  },
  
  requestFullScreen() {
    this.videoContext.requestFullScreen();
  },
  
  onTimeUpdate(e) {
    const currentTime = e.detail.currentTime;
    const duration = e.detail.duration;
    const progress = (currentTime / duration * 100).toFixed(2);
    console.log(`播放进度: ${progress}%`);
  }
});

5. 自定义组件

创建自定义组件

  1. 在项目根目录创建components文件夹
  2. components下创建组件文件夹(如my-component
  3. 在组件文件夹中创建4个文件:.js.json.wxml.wxss
// components/my-component/my-component.js
Component({
  // 组件属性定义
  properties: {
    title: {
      type: String,
      value: '默认标题',
      observer: function(newVal, oldVal) {
        console.log('title改变:', oldVal, '→', newVal);
      }
    },
    count: {
      type: Number,
      value: 0
    },
    show: {
      type: Boolean,
      value: true
    },
    list: {
      type: Array,
      value: []
    },
    config: {
      type: Object,
      value: {}
    }
  },
  
  // 组件内部数据
  data: {
    internalData: '内部数据'
  },
  
  // 组件生命周期
  lifetimes: {
    attached() {
      console.log('组件被添加到页面');
    },
    detached() {
      console.log('组件从页面移除');
    }
  },
  
  // 组件方法
  methods: {
    onTap() {
      // 触发自定义事件
      this.triggerEvent('customevent', {
        detail: {
          value: '触发事件的数据'
        }
      });
      
      // 更新properties
      this.setData({
        count: this.data.count + 1
      });
    },
    
    // 对外暴露的方法
    publicMethod() {
      return '这是对外暴露的方法';
    }
  },
  
  // 外部样式类
  externalClasses: ['external-class']
});
// components/my-component/my-component.json
{
  "component": true,
  "usingComponents": {
    "other-component": "../other-component/other-component"
  }
}
<!-- components/my-component/my-component.wxml -->
<view class="my-component {{externalClass}}">
  <text>{{title}}</text>
  <text>计数: {{count}}</text>
  
  <view wx:if="{{show}}">
    <text>显示内容</text>
  </view>
  
  <view wx:for="{{list}}" wx:key="index">
    {{index}}: {{item}}
  </view>
  
  <button bindtap="onTap">点击触发事件</button>
  
  <!-- 使用其他组件 -->
  <other-component />
  
  <!-- 插槽 -->
  <slot name="header"></slot>
  <view>
    <slot></slot> <!-- 默认插槽 -->
  </view>
  <slot name="footer"></slot>
</view>
/* components/my-component/my-component.wxss */
.my-component {
  padding: 20rpx;
  border: 1rpx solid #e0e0e0;
  border-radius: 8rpx;
}

.my-component text {
  display: block;
  margin-bottom: 10rpx;
}

使用自定义组件

// 页面的json文件
{
  "usingComponents": {
    "my-component": "/components/my-component/my-component"
  }
}
<!-- 页面wxml -->
<view>
  <my-component 
    title="自定义标题"
    count="{{count}}"
    show="{{true}}"
    list="{{['A', 'B', 'C']}}"
    external-class="custom-style"
    bind:customevent="onCustomEvent">
    
    <!-- 插槽内容 -->
    <view slot="header">头部插槽</view>
    <view>默认插槽内容</view>
    <view slot="footer">底部插槽</view>
  </my-component>
</view>

组件通信方式

  1. 父传子:通过properties传递数据
  2. 子传父:通过triggerEvent触发自定义事件
  3. 获取组件实例:通过this.selectComponent('#id')获取子组件实例
  4. 全局数据:通过getApp().globalData共享数据
  5. 事件总线:通过全局事件管理器实现组件间通信

组件实例获取与调用

Page({
  onReady() {
    // 获取组件实例
    const myComponent = this.selectComponent('#my-component');
    
    if (myComponent) {
      // 调用组件方法
      const result = myComponent.publicMethod();
      console.log('调用组件方法结果:', result);
      
      // 更新组件数据
      myComponent.setData({
        title: '通过父组件修改'
      });
    }
  },
  
  onCustomEvent(e) {
    console.log('收到子组件事件:', e.detail);
  }
});

组件样式隔离

  • apply-shared:组件接受组件外部的样式
  • shared:组件接受组件外部的样式,且组件的样式也影响其他组件
  • isolated:组件样式隔离(默认)
  • page-isolated:页面样式隔离
{
  "component": true,
  "styleIsolation": "apply-shared"
}

补充说明

  • 自定义组件可以嵌套使用,形成组件树
  • 组件应尽量保持低耦合、高内聚
  • 复杂的组件应拆分为多个简单组件
  • 合理使用slot提高组件复用性
  • 注意组件性能,避免不必要的渲染

由于篇幅限制,这里先提供移动端答案的前三部分(小程序基础、微信小程序架构、小程序组件)。后续部分(小程序API、小程序样式、小程序路由、小程序性能优化、小程序调试与发布、小程序常见问题)将根据相同模式继续编写,每部分包含问题概述、详细答案、代码示例和对比表格。