微信小程序核心技术栈

微信小程序核心技术栈

WXML

一.WXML基础概念

1.本质与特点

  • 基于 XML 的模板语言,类似 HTML 但具有动态绑定能力
  • 与 JavaScript 逻辑层分离,通过数据驱动视图更新
  • 支持模块化,可通过 复用代码片段

2.与HTML的主要差异

特性 WXML HTML
数据绑定 {{ }} 语法 无原生支持
事件绑定 bind/catch前缀 on前缀
条件渲染 wx:if/wx:for指令 需手动操作DOM
模版系统 < template> 支持数据传入 无标准模板方案

二.数据绑定

1.基础绑定

javascript 复制代码
<!-- 文本插值 -->
<view>Hello {{name}}!</view>

<!-- 属性绑定 -->
<input placeholder="{{placeholderText}}" />

<!-- 表达式支持 -->
<view>{{ age + 1 }}</view>
<view>{{ flag ? 'ON' : 'OFF' }}</view>

2.高级绑定模式

javascript 复制代码
<template is="user-card" data="{{...userInfo, extraData: 123}}"/>
  • 对象展开绑定:

  • 计算属性模拟:

javascript 复制代码
// JS 中预处理数据
Page({
  data: {
    items: [1, 2, 3],
    computedItems: [] // 通过函数计算后 setData
  },
  onLoad() {
    this.setData({
      computedItems: this.data.items.map(x => x * 2)
    })
  }
})

3.数据绑定限制

  • 不支持函数调用:{{ Math.round(price) }} ❌
  • 不支持复杂表达式:{{ value1 + value2 === 3 ? 'Y' : 'N' }} ✅
  • 不支持直接修改数据:必须在 JS 中使用 setData

三.条件渲染

1.基础条件判断

javascript 复制代码
<view wx:if="{{score >= 90}}">优秀</view>
<view wx:elif="{{score >= 60}}">及格</view>
<view wx:else>不及格</view>

2.多条件渲染优化

  • hidden属性(适用于频繁切换的场景):
javascript 复制代码
<view hidden="{{!isActive}}">内容</view>

原理:通过 display:none 控制显示

对比 wx:if :

  • wx:if : 动态添加/移除DOM

3.条件渲染性能建议

场景 推荐方案 理由
初始不显示且后续少切换 wx:if 减少初始 DOM 节点数
需要频繁切换显示状态 hidden 避免频繁操作 DOM

四.列表渲染

1.基础列表

javascript 复制代码
<view wx:for="{{items}}" wx:key="id">
  索引:{{index}},值:{{item.name}}
</view>

2.进阶用法

  • 指定索引/项变量名:
javascript 复制代码
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itm">
  {{idx}}: {{itm}}
</view>
javascript 复制代码
Page({
  data: {
    array: ['苹果', '香蕉', '橙子']
  }
})
javascript 复制代码
0: 苹果
1: 香蕉
2: 橙子
  • 嵌套列表
javascript 复制代码
<block wx:for="{{nestedArray}}">
  <view wx:for="{{item.subItems}}" wx:key="*this">
    {{item}}
  </view>
</block>
javascript 复制代码
Page({
  data: {
    nestedArray: [
      { subItems: ['子项1-1', '子项1-2'] },
      { subItems: ['子项2-1', '子项2-2'] }
    ]
  }
})
javascript 复制代码
子项1-1
子项1-2
子项2-1
子项2-2
  • < view wx:for="{{item.subItems}}" wx:key="*this">:针对外层数组中每个元素的 subItems 属性(这是一个子数组)再次使用 wx:for 指令进行遍历。wx:key="*this" 表示把当前遍历的元素自身当作唯一键值,这样能提升渲染效率。

3.wx:key的深度解析

  • 作用原理:复用已有节点,避免重新创建
  • 正确写法:
javascript 复制代码
<!-- 唯一 ID -->
<view wx:for="{{users}}" wx:key="id"></view>

<!-- 数组项本身(适用于基本类型数组) -->
<view wx:for="{{[1,2,3]}}" wx:key="*this"></view>
  • 错误示例:
javascript 复制代码
<!-- 避免使用 index 作为 key -->
<view wx:for="{{items}}" wx:key="index"></view>

五.模版系统

1.定义模版

javascript 复制代码
<!-- templates/user.wxml -->
<template name="userCard">
  <view class="card">
    <text>姓名:{{user.name}}</text>
    <text>年龄:{{user.age}}</text>
    <slot></slot>  <!-- 插槽支持 -->
  </view>
</template>

2.使用模版

javascript 复制代码
<!-- 页面中引入 -->
<import src="../../templates/user.wxml"/>

<!-- 基本使用 -->
<template is="userCard" data="{{user}}"/>

<!-- 带插槽内容 -->
<template is="userCard" data="{{user}}">
  <view>这是插入的内容</view>
</template>
javascript 复制代码
<template name="userCard">
  <view class="user-card">
    <view>姓名: {{user.name}}</view>
    <view>年龄: {{user.age}}</view>
    <slot></slot>
  </view>
</template>
    

3.动态模版

javascript 复制代码
<template is="{{templateName}}" data="{{...data}}"/>
javascript 复制代码
Page({
  data: {
    templateName: 'userA',
    data: { name: '张三' }
  }
})

六.事件系统

1.事件分类

事件类型 描述 示例事件
冒泡事件 向父节点传递 tap、touchstart
非冒泡事件 不向上传递 input、scroll
###2.事件绑定语法
javascript 复制代码
<!-- 冒泡事件 -->
<view bindtap="handleTap"></view>

<!-- 阻止冒泡 -->
<view catchtap="handleTap"></view>

<!-- 互斥事件(仅一个触发) -->
<view mut-bindtap="handleTap"></view>

3.事件对象详情

javascript 复制代码
Page({
  handleTap(e) {
    console.log(e.type)           // 事件类型
    console.log(e.timeStamp)      // 时间戳
    console.log(e.currentTarget)  // 当前组件
    console.log(e.target)         // 触发源组件
    console.log(e.detail)         // 自定义数据
    console.log(e.mark)           // 事件标记
  }
})

4.自定义数据传递

javascript 复制代码
<view data-id="123" bindtap="handleTap">点击</view>
javascript 复制代码
handleTap(e) {
  console.log(e.currentTarget.dataset.id) // "123"
}

七.WXML特殊组件

1.< block> 标签

  • 虚拟容器:不渲染真实节点,仅用于逻辑分组
  • 典型场景:

< block wx:if="{{show}}">

< view>A

< view>B

< /block>

2.< wxs>脚本模块

  • 作用:在WXML中处理数据(类似过滤器)
  • 示例:
javascript 复制代码
<wxs module="m1">
  function formatPrice(price) {
    return '¥' + price.toFixed(2)
  }
  module.exports = {
    formatPrice: formatPrice
  }
</wxs>

<view>{{m1.formatPrice(100)}}</view>

八.最佳实践与性能优化

1.避免过深的嵌套层级(建议不超过5层)

2.减少不必要的数据绑定:

javascript 复制代码
<!-- 不推荐 -->
<view>{{ largeObject.text }}</view>

<!-- 推荐 -->
<view>{{ text }}</view>

3.使用key提升列表性能(尤其对动态排序列表)

4.复杂逻辑移至js处理,保持模版简洁

WXSS

一、WXSS基础概念

1.本质与特点

  • 基于 CSS 的样式语言,扩展了响应式像素单位(rpx)
  • 与 Web CSS 的兼容性:支持大多数 CSS2.1 和部分 CSS3 特性
  • 样式隔离机制:默认局部作用域,避免样式污染

2. 与 Web CSS 的主要差异

特性 WXSS CSS
单位系统 新增rpx响应式单位 传统 px/em/rem
样式导入 @import 支持相对路径 支持多种导入方式
选择器支持 部分伪类不支持(如:hover) 完整支持
全局/局部样式 通过文件路径自动隔离 需手动管理

二、尺寸单位

1.核心单位对比

单位 计算方式 适用场景
rpx 1rpx = 屏幕宽度 / 750 推荐 响应式布局
px 1px = 物理像素 固定尺寸元素(如边框)
vw/vh 1vw = 视图宽度1% 特殊全屏布局
% 相对于父元素 传统百分比布局

2.rpx适配原理

  • 基准设备:iPhone6(屏幕宽度375pt)
  • 换算关系:
javascript 复制代码
设备         宽度(pt)  1rpx换算
iPhone6      375        0.5px
iPhoneX      375        0.5px 
iPad         768        1.024px

3.单位使用建议

javascript 复制代码
/* 推荐方案 */
.container {
  width: 750rpx; /* 满屏宽度 */
  padding: 32rpx; /* 通用间距 */
  font-size: 28rpx; /* 基础字号 */
}

/* 特殊情况使用 px */
.border {
  border: 1px solid #ddd; /* 物理像素边框 */
}

三、样式导入与作用域

1.导入方式

javascript 复制代码
/* 导入相对路径样式文件 */
@import "../../common/base.wxss";

/* 引入 iconfont */
@font-face {
  font-family: 'iconfont';
  src: url('https://at.alicdn.com/t/font_123456.woff2');
}

2.样式隔离规则

样式类型 作用范围 示例文件
全局样式 所有页面 推荐 响应式布局
页面样式 当前页面 pages/index/index.wxss
组件样式 当前自定义组件 components/my-component/my-component.wxss

3.强制样式穿透

javascript 复制代码
/* 方法1:添加 !important */
.text {
  color: red !important;
}

/* 方法2:使用 >>> 或 ::v-deep(部分版本支持) */
.parent >>> .child {
  font-size: 32rpx;
}

四、选择器系统

1.支持的选择器类型

类型 示例 说明
类选择器 .container 最常用
ID选择器 #header 避免滥用
元素选择器 view 匹配组件标签
伪类选择器 ::after 仅支持部分伪类
属性选择器 [data-type="1"] 需注意性能
后代选择器 .parent .child 避免过深嵌套(≤3层)

2.不支持的选择器

  • 通配符选择器(*)
  • 部分伪类(如:hover、:focus)
  • 兄弟选择器(~、+)

3.选择器优先级

javascript 复制代码
/* 优先级从高到低 */
!important > 行内样式 > ID > Class/属性 > 元素

五、Flex布局(官方推荐方案)

1.基本使用

javascript 复制代码
.container {
  display: flex;
  flex-direction: row; /* 主轴方向:row | column */
  justify-content: center; /* 主轴对齐 */
  align-items: flex-start; /* 交叉轴对齐 */
  flex-wrap: wrap; /* 换行控制 */
}

2.常用布局模式

  • 水平等分布局
javascript 复制代码
.item {
  flex: 1; /* 等分容器 */
  min-width: 0; /* 防止内容溢出 */
}
  • 垂直居中
javascript 复制代码
.center {
  display: flex;
  justify-content: center;
  align-items: center;
}

3.兼容性注意

  • 小程序全版本支持 Flex 布局
  • 避免使用 gap 属性(需用 margin 替代)

六、WXSS高级特性

1.变量与计算

javascript 复制代码
/* 定义全局变量(需配合 JS 实现) */
page {
  --theme-color: #ff0000;
}

/* 使用变量 */
.text {
  color: var(--theme-color);
}

2.媒体查询

javascript 复制代码
/* 根据屏幕宽度适配 */
@media screen and (min-width: 768px) {
  .card {
    width: 80%;
  }
}

3.动画支持

javascript 复制代码
/* 定义关键帧 */
@keyframes slidein {
  from { transform: translateX(100%); }
  to { transform: translateX(0); }
}

/* 应用动画 */
.box {
  animation: slidein 0.5s ease-in-out;
}

JavaScript

一、小程序JS运行环境

1.双线程架构

线程类型 运行环境 职责
逻辑层 JavaScriptCore / V8 数据处理、API调用
渲染层 WebView 页面渲染、事件响应

2.与浏览器JS的差异

特性 小程序JS 浏览器JS
DOM/BOM 不可用 完整支持
全局对象 wx代替window window
模块系统 CommonJs ES Modules
异步API 回调/Promise混用 主流Promise

二、App和Page生命周期

1.App生命周期(全局)

javascript 复制代码
App({
  // 生命周期
  onLaunch(options) {
    // 初始化完成时触发(全局一次)
    console.log('场景值:', options.scene) 
  },
  onShow(options) {
    // 小程序启动或从后台进入前台
  },
  onHide() {
    // 小程序从前台进入后台
  },
  
  // 自定义全局方法/数据
  globalData: {
    userInfo: null
  },
  
  // 自定义全局函数
  fetchData() {
    return wx.request({url: 'https://api.example.com'})
  }
})

2.Page生命周期(全局)

javascript 复制代码
Page({
  // 生命周期
  onLoad(options) {
    // 页面创建时触发,接收路由参数
  },
  onShow() {
    // 页面显示/切入前台时触发
  },
  onReady() {
    // 页面初次渲染完成
  },
  onHide() {
    // 页面隐藏/切入后台
  },
  onUnload() {
    // 页面卸载时触发(跳转或关闭)
  },
  
  // 页面事件处理
  onPullDownRefresh() {
    // 处理下拉刷新
    wx.stopPullDownRefresh()
  },
  onReachBottom() {
    // 页面上拉触底
  },
  onPageScroll(e) {
    // 页面滚动时触发
    console.log(e.scrollTop)
  },
  onShareAppMessage() {
    // 用户点击分享时触发
    return { title: '分享标题' }
  }
})

三、数据绑定与更新机制

1.数据初始化

javascript 复制代码
Page({
  data: {
    message: 'Hello',
    list: [],
    user: { name: '张三', age: 20 }
  }
})

2.setData 深度解析

复制代码
在微信小程序里,页面的data对象用来存储页面的数据。当你需要动态更新页面上的数据,并且让界面随之刷新以反映这些数据的变化时,就可以使用this.setData方法。

基本用法

javascript 复制代码
this.setData({
  'message': 'New Value',
  'user.age': 21  // 支持路径写法
})

高级特性

  • 异步更新:多个setData会合并执行
  • 性能优化:
javascript 复制代码
// 错误示范(频繁更新)
for(let i=0; i<100; i++) {
  this.setData({ count: i })
}

// 正确做法(批量更新)
this.setData({ 
  count: 100,
  'list[0].name': '李四'
})

四、事件处理系统

1.事件绑定与传参

javascript 复制代码
<!-- WXML 中绑定 -->
<view bindtap="handleTap" data-id="123">点击</view>
<view bindinput="handleInput"></view>
  • 1.通过dataset传参
    可以在组件上使用**data-自定义属性来传递参数。在事件处理函数中,可以通过event.currentTarget.dataset*来获取这些参数。
javascript 复制代码
<!-- pages/index/index.wxml -->
<view bindtap="handleTap" data-id="123" data-name="example">点击我</view>
javascript 复制代码
// pages/index/index.js
Page({
  handleTap: function(event) {
    const id = event.currentTarget.dataset.id;
    const name = event.currentTarget.dataset.name;
    console.log('传递的 id:', id);
    console.log('传递的 name:', name);
  }
})
  • 全局变量传参
    如果需要传递复杂的数据,可以使用全局变量,在app,.js中定义全局变量,然后在页面中通过**getApp()**方法来访问和修改这些变量。
javascript 复制代码
// app.js
App({
  globalData: {
    userInfo: null
  }
})
javascript 复制代码
// pages/index/index.js
Page({
  onLoad: function() {
    const app = getApp();
    app.globalData.userInfo = {
      name: 'John',
      age: 25
    };
  },
  handleTap: function() {
    const app = getApp();
    const userInfo = app.globalData.userInfo;
    console.log('全局变量中的用户信息:', userInfo);
  }
})
  • 3.事件对象本事传参
    有些事件对象本身会携带一些有用的信息,例如touchstart、touchmove、touchend等触摸事件,会携带触摸点的坐标信息。
javascript 复制代码
<!-- pages/index/index.wxml -->
<view bindtouchstart="handleTouchStart">触摸我</view>
javascript 复制代码
// pages/index/index.js
Page({
  handleTouchStart: function(event) {
    const touch = event.touches[0];
    const x = touch.clientX;
    const y = touch.clientY;
    console.log('触摸点的 x 坐标:', x);
    console.log('触摸点的 y 坐标:', y);
  }
})

综合示例

javascript 复制代码
<!-- pages/index/index.wxml -->
<view>
  <view wx:for="{{list}}" wx:key="*this" bindtap="handleItemTap" data-index="{{index}}">
    {{item}}
  </view>
</view>
javascript 复制代码
// pages/index/index.js
Page({
  data: {
    list: ['苹果', '香蕉', '橙子']
  },
  handleItemTap: function(event) {
    const index = event.currentTarget.dataset.index;
    const item = this.data.list[index];
    console.log('点击的是第', index + 1, '项:', item);
  }
})

2.事件对象结构

javascript 复制代码
Page({
  handleTap(e) {
    console.log(e.type)          // 事件类型(如 tap)
    console.log(e.currentTarget) // 绑定事件的组件
    console.log(e.target)        // 触发事件的源组件
    console.log(e.detail)        // 额外信息(如 input 的值)
    console.log(e.mark)          // 事件标记数据
  }
})

3.自定义组件

复制代码
在微信小程序里,自定义事件是实现组件间通信的重要手段,可用于实现父组件向子组件、子组件向父组件,以及兄弟组件间的通信。

子组件向父组件通信

子组件可通过触发自定义事件并携带数据,将信息传递给父组件。父组件监听该自定义事件,在事件处理函数中接收数据。
子组件代码

javascript 复制代码
// components/child/child.js
Component({
  methods: {
    sendDataToParent() {
      const data = '这是来自子组件的数据';
      // 触发自定义事件,并传递数据
      this.triggerEvent('customEvent', { data });
    }
  }
})
javascript 复制代码
<!-- components/child/child.wxml -->
<button bindtap="sendDataToParent">向父组件发送数据</button>

父组件代码

javascript 复制代码
// pages/parent/parent.js
Page({
  handleCustomEvent(e) {
    const receivedData = e.detail.data;
    console.log('接收到子组件的数据:', receivedData);
  }
})
javascript 复制代码
<!-- pages/parent/parent.wxml -->
<child bind:customEvent="handleCustomEvent"></child>

父组件向子组件通信
子组件代码

javascript 复制代码
// components/child/child.js
Component({
  properties: {
    parentData: {
      type: String,
      value: ''
    }
  },
  attached() {
    console.log('接收到父组件的数据:', this.data.parentData);
  }
})
javascript 复制代码
<!-- components/child/child.wxml -->
<view>父组件传递的数据: {{parentData}}</view>

父组件代码

javascript 复制代码
// pages/parent/parent.js
Page({
  data: {
    dataToChild: '这是来自父组件的数据'
  }
})
javascript 复制代码
<!-- pages/parent/parent.wxml -->
<child parent-data="{{dataToChild}}"></child>

兄弟组件间通信

复制代码
兄弟组件间通信可借助共同的父组件作为中间桥梁。一个兄弟组件触发自定义事件将数据传递给父组件,父组件再将数据传递给另一个兄弟组件。

组件A代码

javascript 复制代码
// components/componentA/componentA.js
Component({
  methods: {
    sendDataToParent() {
      const data = '这是来自组件A的数据';
      this.triggerEvent('customEvent', { data });
    }
  }
})
javascript 复制代码
<!-- components/componentA/componentA.wxml -->
<button bindtap="sendDataToParent">向父组件发送数据</button>

组件B代码

javascript 复制代码
// components/componentB/componentB.js
Component({
  properties: {
    siblingData: {
      type: String,
      value: ''
    }
  },
  attached() {
    console.log('接收到兄弟组件的数据:', this.data.siblingData);
  }
})
javascript 复制代码
<!-- components/componentB/componentB.wxml -->
<view>兄弟组件传递的数据: {{siblingData}}</view>

父组件代码

javascript 复制代码
// pages/parent/parent.js
Page({
  data: {
    dataToComponentB: ''
  },
  handleCustomEvent(e) {
    const receivedData = e.detail.data;
    this.setData({
      dataToComponentB: receivedData
    });
  }
})
javascript 复制代码
<!-- pages/parent/parent.wxml -->
<componentA bind:customEvent="handleCustomEvent"></componentA>
<componentB sibling-data="{{dataToComponentB}}"></componentB>

组件化开发

一、组件基础概念

1.组件vs页面

特性 组件 页面
配置文件 需声明 "component": true 无需特殊声明
初始化方式 Component() Page()
作用域 样式/数据隔离 全局样式可影响
用途 回调/功能复用 业务主视图

2.组件文件结构

javascript 复制代码
components/
  ├─ my-component/
     ├─ my-component.js     # 组件逻辑
     ├─ my-component.json   # 组件配置
     ├─ my-component.wxml   # 组件模板
     ├─ my-component.wxss   # 组件样式

二、组件创建全流程

1.配置组件

javascript 复制代码
// my-component.json
{
  "component": true,
  //"usingComponents":这是一个对象,用于声明当前组件所使用的其他自定义组件。在这个对象里,键是自定义组件在模板中使用的标签名,值是自定义组件的路径。
  "usingComponents": {
  //"child-comp": "../child/child":这一配置表示在当前组件里,能够使用名为child-comp的自定义组件,该组件的路径是../child/child。
    "child-comp": "../child/child"  # 嵌套组件声明
  }
}

父组件

javascript 复制代码
//parent.json
{
  "component": true,
  "usingComponents": {
    "child-comp": "../child/child"
  }
}
//parent.wxml
<view>
  这是父组件
  <child-comp></child-comp>
</view>
//parent.js
Component({
  properties: {
    // 父组件的属性
  },
  methods: {
    // 父组件的方法
  }
})

子组件

javascript 复制代码
//child.json
{
  "component": true
}
//child.wxml

```javascript
<view>这是子组件</view>
//child.js
Component({
  properties: {
    // 子组件的属性
  },
  methods: {
    // 子组件的方法
  }
})
复制代码
### 2.组件构造函数

```javascript
// my-component.js
Component({
  // 组件属性定义(对外接口)
  properties: {
    title: {
      type: String,
      value: '默认标题',
      observer(newVal, oldVal) {
        // 属性变化监听
      }
    }
  },

  // 组件内部数据
  data: {
    count: 0
  },

  // 生命周期
  lifetimes: {
    attached() {
      console.log('组件实例进入页面节点树')
    },
    detached() {
      console.log('组件实例被移除')
    }
  },

  // 页面生命周期(所在页面的生命周期)
  pageLifetimes: {
    show() { /* 页面显示 */ },
    hide() { /* 页面隐藏 */ }
  },

  // 方法
  methods: {
    handleTap() {
      this.setData({ count: this.data.count + 1 })
      this.triggerEvent('countchange', { value: this.data.count })
    }
  }
})

三、组件通信机制

1.父 → 子通信

方式一:Properties 传递

javascript 复制代码
<!-- 父组件 WXML -->
<my-component title="自定义标题" count="{{parentCount}}"/>

方式二:通过 selectComponent 获取实例

javascript 复制代码
// 父组件 JS
this.selectComponent('#my-comp').setData({ count: 10 })

2. 子 → 父通信

javascript 复制代码
// 子组件触发自定义事件
this.triggerEvent('eventname', {
  detail: { /* 数据 */ },
  bubbles: false,    // 是否冒泡
  composed: false    // 是否跨越组件边界
})

// 父组件监听
<my-component bind:eventname="handleEvent"/>

3. 兄弟组件通信

方案一:通过父组件中转

javascript 复制代码
// 子组件A触发事件 → 父组件 → 子组件B
this.triggerEvent('update', {data: 1})

// 父组件 WXML
<comp-a bind:update="handleUpdate"/>
<comp-b id="comp-b"/>

// 父组件 JS
handleUpdate(e) {
  this.selectComponent('#comp-b').setData(e.detail)
}

方案二:使用全局事件总线

javascript 复制代码
// app.js 中定义
App({
  eventBus: {
    emit(event, data) { /*...*/ },
    on(event, callback) { /*...*/ }
  }
})

// 组件中使用
getApp().eventBus.emit('update', {data: 1})

四、组件高级特性

1. 插槽系统(Slot)

基础用法

javascript 复制代码
<!-- 组件模板 -->
<view class="container">
  <slot></slot>
</view>

<!-- 使用组件 -->
<my-component>
  <view>插入的内容</view>
</my-component>

具名插槽

javascript 复制代码
<!-- 组件模板 -->
<slot name="header"></slot>
<slot name="footer"></slot>

<!-- 使用组件 -->
<my-component>
  <view slot="header">头部</view>
  <view slot="footer">底部</view>
</my-component>

2.样式隔离配置

javascript 复制代码
Component({
  options: {
    styleIsolation: 'isolated' // 可选值:
      // isolated - 完全隔离
      // apply-shared - 父影响子
      // shared - 相互影响
  }
})

3.外部样式类

javascript 复制代码
// 组件 JS
Component({
  externalClasses: ['custom-class'] // 接受外部样式类
})

<!-- 组件 WXML -->
<view class="custom-class">内容</view>

<!-- 使用组件 -->
<my-component custom-class="red-text"/>

动态组件实现

javascript 复制代码
<!-- 动态加载组件 -->
<component is="{{componentName}}"/>

<!-- 配合 wx:if -->
<view wx:if="{{type === 'A'}}">
  <comp-a/>
</view>
<view wx:else>
  <comp-b/>
</view>

API体系

一、API 基础架构

1. 调用方式

调用形式 示例 特点
同步 API wx.setStorageSync(key, data) 立即返回结果,命名包含 Sync
异步 API(回调) wx.request({ success(){} }) 通过回调函数处理结果
异步 API(Promise) wx.request().then() 需自行封装或使用云开发 SDK

2.运行环境限制

  • 部分 API 需声明权限:在 app.json 中配置
javascript 复制代码
{
  "permission": {
    "scope.userLocation": {
      "desc": "获取位置信息"
    }
  }
}
  • 安全域名限制:网络请求必须配置合法域名(开发阶段可关闭校验)

二、核心 API 分类详解

1. 网络请求

基础请求

javascript 复制代码
wx.request({
  url: 'https://api.example.com',
  method: 'POST',
  data: { key: 'value' },
  header: { 'Content-Type': 'application/json' },
  success(res) {
    console.log(res.statusCode, res.data)
  },
  fail(err) {
    console.error(err)
  }
})

高级特性

  • 文件上传:
javascript 复制代码
wx.uploadFile({
  url: 'https://upload.example.com',
  filePath: tempFilePaths[0],
  name: 'file',
  success(res) {
    console.log(res.data)
  }
})
  • WebSocket
javascript 复制代码
const socket = wx.connectSocket({
  url: 'wss://echo.websocket.org'
})
socket.onMessage(msg => console.log(msg))

2.数据缓存

操作类型 同步方法 异步方法
存储 wx.setStorageSync wx.setStorage
读取 wx.getStorageSync wx.getStorage
删除 wx.removeStorageSync wx.removeStorage
清空 wx.clearStorageSync wx.clearStorage
javascript 复制代码
// 敏感数据建议加密存储
const crypto = require('./crypto-utils')
wx.setStorageSync('token', crypto.encrypt(rawToken))

3.界面交互

弹窗系列

javascript 复制代码
// 显示加载框
wx.showLoading({ title: '加载中' })
setTimeout(() => wx.hideLoading(), 2000)

// 模态对话框
wx.showModal({
  title: '提示',
  content: '确认删除?',
  success(res) {
    if (res.confirm) console.log('用户确认')
  }
})

导航控制

javascript 复制代码
// 页面跳转(保留当前页)
wx.navigateTo({ url: '/pages/detail?id=1' })

// Tab页切换
wx.switchTab({ url: '/pages/index' })

// 返回上一页
wx.navigateBack({ delta: 1 })

4.设备能力

地理位置

javascript 复制代码
wx.getLocation({
  type: 'wgs84',
  success(res) {
    const { latitude, longitude } = res
    wx.openLocation({ latitude, longitude })
  }
})

扫码功能

javascript 复制代码
wx.scanCode({
  success(res) {
    console.log('扫码结果:', res.result)
  }
})

5.媒体处理

图片处理

javascript 复制代码
// 选择图片
wx.chooseImage({
  count: 1,
  sizeType: ['compressed'],
  success(res) {
    wx.previewImage({ urls: res.tempFilePaths })
  }
})

录音功能

javascript 复制代码
const recorderManager = wx.getRecorderManager()
recorderManager.onStart(() => console.log('录音开始'))
recorderManager.start({ format: 'mp3' })

6.开放接口

用户信息

javascript 复制代码
wx.getUserProfile({
  desc: '用于完善会员资料',
  success(res) {
    console.log(res.userInfo)
  }
})

微信支付

javascript 复制代码
wx.requestPayment({
  timeStamp: '',
  nonceStr: '',
  package: '',
  signType: 'MD5',
  paySign: '',
  success(res) { /* 支付成功 */ }
})

三、API 高级用法

1. Promise 化封装

javascript 复制代码
// 通用封装方法
const promisify = (api) => (options) => 
  new Promise((resolve, reject) => {
    api({
      ...options,
      success: resolve,
      fail: reject
    })
  })

// 使用示例
const request = promisify(wx.request)
request({ url: 'https://api.example.com' })
  .then(res => console.log(res.data))

2. 并发请求控制

javascript 复制代码
// 使用 Promise.all
Promise.all([
  promisify(wx.request)({ url: '/api/user' }),
  promisify(wx.request)({ url: '/api/goods' })
]).then(([userRes, goodsRes]) => {
  console.log(userRes, goodsRes)
})

3. 自定义拦截器

javascript 复制代码
// 请求拦截示例
const originalRequest = wx.request
wx.request = function(options) {
  // 添加全局 header
  options.header = {
    ...options.header,
    'X-Token': wx.getStorageSync('token')
  }
  return originalRequest(options)
}
相关推荐
三巧1 分钟前
纯CSS吃豆人(JS仅控制进度)
javascript·css·html
SummerGao.2 分钟前
【解决】layui layer的提示框,弹出框一闪而过的问题
前端·layui
软件技术NINI18 分钟前
html css js网页制作成品——HTML+CSS+js美甲店网页设计(5页)附源码
javascript·css·html
天天扭码30 分钟前
从数组到对象:JavaScript 遍历语法全解析(ES5 到 ES6 + 超详细指南)
前端·javascript·面试
拉不动的猪32 分钟前
前端开发中常见的数据结构优化问题
前端·javascript·面试
街尾杂货店&32 分钟前
css word
前端·css
Мартин.35 分钟前
[Meachines] [Hard] CrimeStoppers LFI+ZIP-Shell+Firefox-Dec+DLINK+rootme-0.5
前端·firefox
冰镇生鲜35 分钟前
快速静态界面 MDC规则约束 示范
前端
技术与健康1 小时前
【解读】Chrome 浏览器实验性功能全景
前端·chrome
Bald Monkey1 小时前
【Element Plus】解决移动设备使用 el-menu 和 el-sub-menu 时,子菜单需要点击两次才会隐藏的问题
前端·elementui·vue·element plus