微信小程序入门学习教程,从入门到精通,微信小程序常用API(下)——知识点详解 + 案例实战(5)

微信小程序常用API(下)


一、动画 API(用于罗盘动画)

1.1 知识点说明

微信小程序通过 wx.createAnimation() 创建动画实例,通过链式调用设置动画属性(如旋转、缩放、位移、透明度等),最后通过 export() 导出动画数据并绑定到 WXML 元素。

1.2 语法

js 复制代码
const animation = wx.createAnimation({
  duration: 1000,        // 动画持续时间,单位 ms
  timingFunction: 'ease', // 动画缓动函数
  delay: 0,              // 延迟时间
  transformOrigin: '50% 50%' // 动画基点
});

常用方法:

  • rotate(deg):旋转
  • scale(x, y):缩放
  • translate(x, y):平移
  • opacity(value):透明度
  • step():表示一组动画结束
  • export():导出动画数据

1.3 案例代码:罗盘动画

js 复制代码
// pages/compass/compass.js
Page({
  data: {
    animationData: {} // 用于绑定到 WXML
  },

  onShow() {
    this.startCompassAnimation();
  },

  startCompassAnimation() {
    const animation = wx.createAnimation({
      duration: 2000,
      timingFunction: 'linear',
      delay: 0
    });

    // 持续旋转 360 度(可循环)
    animation.rotate(360).step();
    this.setData({
      animationData: animation.export()
    });

    // 循环动画:2秒后再次调用
    setTimeout(() => {
      this.startCompassAnimation();
    }, 2000);
  }
});
xml 复制代码
<!-- pages/compass/compass.wxml -->
<view class="compass-container">
  <image 
    class="compass" 
    src="/images/compass.png" 
    animation="{{animationData}}"
  ></image>
</view>
css 复制代码
/* pages/compass/compass.wxss */
.compass-container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}
.compass {
  width: 200rpx;
  height: 200rpx;
}

二、用户登录相关 API

2.1 登录流程时序

  1. 小程序调用 wx.login() 获取临时登录凭证 code
  2. code 发送到开发者服务器
  3. 服务器用 code + appid + secret 向微信接口换取 openidsession_key
  4. 服务器生成自定义登录态(如 token)返回给小程序
  5. 小程序使用 wx.setStorageSync() 缓存 token

2.2 关键 API

  • wx.login()
  • wx.request()
  • wx.setStorageSync() / wx.getStorageSync()
  • wx.getUserProfile()(获取用户头像、昵称)

2.3 案例代码:用户登录

js 复制代码
// pages/login/login.js
Page({
  data: {
    userInfo: null,
    hasLogin: false
  },

  // 登录主流程
  async handleLogin() {
    try {
      // 1. 获取 code
      const { code } = await wx.login();
      console.log('临时登录凭证 code:', code);

      // 2. 发送 code 到后端换取 token
      const res = await wx.request({
        url: 'https://your-server.com/api/login',
        method: 'POST',
        data: { code },
        header: { 'content-type': 'application/json' }
      });

      const { token, openid } = res.data;
      if (token) {
        // 3. 缓存 token
        wx.setStorageSync('token', token);
        wx.setStorageSync('openid', openid);
        this.setData({ hasLogin: true });
        console.log('登录成功');
      }
    } catch (err) {
      console.error('登录失败', err);
    }
  },

  // 获取用户头像和昵称(需用户主动触发)
  getUserProfile() {
    wx.getUserProfile({
      desc: '用于完善用户资料', // 声明用途
      success: (res) => {
        this.setData({
          userInfo: res.userInfo
        });
        wx.setStorageSync('userInfo', res.userInfo);
      },
      fail: (err) => {
        console.log('用户拒绝授权', err);
      }
    });
  }
});
xml 复制代码
<!-- pages/login/login.wxml -->
<view class="container">
  <button wx:if="{{!hasLogin}}" bindtap="handleLogin">一键登录</button>
  
  <view wx:if="{{hasLogin && !userInfo}}">
    <button bindtap="getUserProfile">获取头像昵称</button>
  </view>

  <view wx:if="{{userInfo}}" class="user-info">
    <image src="{{userInfo.avatarUrl}}" class="avatar"></image>
    <text>{{userInfo.nickName}}</text>
  </view>
</view>

⚠️ 注意:wx.getUserInfo() 已废弃,必须使用 wx.getUserProfile() 且需用户主动点击触发。


三、地图与位置 API(查看附近美食)

3.1 核心 API

  • wx.getLocation():获取当前位置
  • <map> 组件:展示地图
  • 腾讯地图 WebService API:用于搜索附近 POI(需申请 key)
  • wx.openLocation():打开地图查看位置
  • wx.navigateTo():页面跳转

3.2 案例代码:获取位置并展示附近餐厅

js 复制代码
// pages/restaurant/restaurant.js
Page({
  data: {
    latitude: 0,
    longitude: 0,
    markers: [],
    isLoading: true
  },

  onLoad() {
    this.getCurrentLocation();
  },

  // 获取当前位置
  getCurrentLocation() {
    wx.getLocation({
      type: 'gcj02', // 返回可用于腾讯地图的坐标
      success: (res) => {
        const { latitude, longitude } = res;
        this.setData({ latitude, longitude });
        this.searchNearbyRestaurants(latitude, longitude);
      },
      fail: (err) => {
        wx.showToast({ title: '定位失败', icon: 'none' });
      }
    });
  },

  // 调用腾讯地图 API 搜索附近餐厅
  async searchNearbyRestaurants(lat, lng) {
    const key = 'YOUR_TENCENT_MAP_KEY'; // 替换为你的腾讯地图 key
    const url = `https://apis.map.qq.com/ws/place/v1/search?keyword=美食&location=${lat},${lng}&page_size=10&key=${key}`;

    try {
      const res = await wx.request({ url });
      const markers = res.data.data.map((item, index) => ({
        id: index,
        latitude: item.location.lat,
        longitude: item.location.lng,
        title: item.title,
        callout: { content: item.title, display: 'ALWAYS' }
      }));
      this.setData({ markers, isLoading: false });
    } catch (err) {
      console.error('搜索失败', err);
    }
  },

  // 点击标记查看详情(可跳转)
  onMarkerTap(e) {
    const marker = this.data.markers.find(m => m.id === e.markerId);
    wx.navigateTo({
      url: `/pages/detail/detail?name=${marker.title}&lat=${marker.latitude}&lng=${marker.longitude}`
    });
  }
});
xml 复制代码
<!-- pages/restaurant/restaurant.wxml -->
<view class="map-container">
  <map
    wx:if="{{!isLoading}}"
    id="map"
    longitude="{{longitude}}"
    latitude="{{latitude}}"
    markers="{{markers}}"
    show-location
    bindmarkertap="onMarkerTap"
    style="width: 100%; height: 100vh;"
  ></map>
  <view wx:if="{{isLoading}}" class="loading">定位中...</view>
</view>

四、WebSocket 实时通信(在线聊天)

4.1 核心 API

  • wx.connectSocket():创建 WebSocket 连接
  • wx.onSocketOpen():监听连接成功
  • wx.onSocketMessage():监听服务器消息
  • wx.sendSocketMessage():发送消息
  • wx.closeSocket():关闭连接
  • SocketTask:从基础库 2.10.0 起推荐使用 wx.connectSocket() 返回的 SocketTask 对象管理连接

4.2 案例代码:简易聊天室

js 复制代码
// pages/chat/chat.js
Page({
  data: {
    messages: [],
    inputVal: '',
    socketOpen: false
  },

  socketTask: null,

  onShow() {
    this.connectToServer();
  },

  // 连接 WebSocket 服务器
  connectToServer() {
    const that = this;
    this.socketTask = wx.connectSocket({
      url: 'wss://your-websocket-server.com/chat',
      success: () => console.log('连接请求已发送')
    });

    // 监听连接成功
    this.socketTask.onOpen(() => {
      console.log('WebSocket 连接已打开');
      that.setData({ socketOpen: true });
      that.addSystemMessage('已连接到聊天室');
    });

    // 监听消息
    this.socketTask.onMessage((res) => {
      const msg = JSON.parse(res.data);
      that.addMessage(msg);
    });

    // 监听错误
    this.socketTask.onError((err) => {
      console.error('WebSocket 错误', err);
      that.addSystemMessage('连接异常');
    });

    // 监听关闭
    this.socketTask.onClose(() => {
      console.log('WebSocket 已关闭');
      that.setData({ socketOpen: false });
    });
  },

  addMessage(msg) {
    this.setData({
      messages: [...this.data.messages, msg]
    });
  },

  addSystemMessage(text) {
    this.addMessage({ type: 'system', content: text, time: new Date().toLocaleTimeString() });
  },

  // 发送消息
  sendMessage() {
    if (!this.data.inputVal.trim()) return;
    if (!this.data.socketOpen) {
      wx.showToast({ title: '未连接', icon: 'none' });
      return;
    }

    const msg = {
      type: 'user',
      content: this.data.inputVal,
      time: new Date().toLocaleTimeString()
    };

    this.socketTask.send({
      data: JSON.stringify(msg),
      success: () => {
        this.addMessage(msg);
        this.setData({ inputVal: '' });
      }
    });
  },

  onInput(e) {
    this.setData({ inputVal: e.detail.value });
  },

  // 页面卸载时关闭连接
  onUnload() {
    if (this.socketTask) {
      this.socketTask.close();
    }
  }
});
xml 复制代码
<!-- pages/chat/chat.wxml -->
<view class="chat-container">
  <scroll-view scroll-y class="message-list">
    <view wx:for="{{messages}}" wx:key="index" class="message {{item.type === 'user' ? 'user' : 'system'}}">
      <text>{{item.content}}</text>
      <text class="time">{{item.time}}</text>
    </view>
  </scroll-view>

  <view class="input-area">
    <input 
      value="{{inputVal}}" 
      bindinput="onInput" 
      placeholder="输入消息..." 
      disabled="{{!socketOpen}}"
    />
    <button bindtap="sendMessage" disabled="{{!socketOpen}}">发送</button>
  </view>
</view>
css 复制代码
/* pages/chat/chat.wxss */
.chat-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
}
.message-list {
  flex: 1;
  padding: 20rpx;
  background: #f5f5f5;
}
.message {
  padding: 10rpx;
  margin-bottom: 10rpx;
  border-radius: 10rpx;
}
.user {
  background: #e1f5fe;
  align-self: flex-end;
  text-align: right;
}
.system {
  background: #fff3e0;
  color: #999;
}
.input-area {
  display: flex;
  padding: 20rpx;
  background: white;
}
.input-area input {
  flex: 1;
  border: 1rpx solid #ccc;
  padding: 10rpx;
  margin-right: 20rpx;
}

五、综合性案例:带登录、定位、聊天功能的"附近好友聊天"小程序

功能整合:

  1. 用户登录(获取 openid + 昵称)
  2. 获取当前位置
  3. 显示附近在线用户(模拟)
  4. 点击用户发起 WebSocket 聊天

核心逻辑示意(简化版):

js 复制代码
// pages/main/main.js
Page({
  async onLoad() {
    // 1. 检查是否已登录
    const token = wx.getStorageSync('token');
    if (!token) {
      await this.login();
    }

    // 2. 获取位置
    const loc = await this.getLocation();
    
    // 3. 模拟获取附近用户(实际应由后端根据位置返回)
    this.setData({
      nearbyUsers: [
        { id: 1, name: '张三', distance: '200m', lat: loc.latitude + 0.001, lng: loc.longitude },
        { id: 2, name: '李四', distance: '500m', lat: loc.latitude - 0.001, lng: loc.longitude + 0.001 }
      ]
    });
  },

  async login() {
    const { code } = await wx.login();
    // ... 发送 code 换 token
  },

  getLocation() {
    return new Promise((resolve, reject) => {
      wx.getLocation({
        type: 'gcj02',
        success: resolve,
        fail: reject
      });
    });
  },

  startChat(e) {
    const user = e.currentTarget.dataset.user;
    wx.navigateTo({
      url: `/pages/chat/chat?targetUser=${user.name}`
    });
  }
});

六、本章小结

功能模块 核心 API 注意事项
动画 wx.createAnimation() 需配合 animation 属性绑定
用户登录 wx.login(), wx.getUserProfile() 头像昵称需用户主动授权
数据缓存 wx.setStorageSync() 同步方法更简洁
地图定位 wx.getLocation(), <map> 组件 坐标系用 gcj02
WebSocket wx.connectSocket() + SocketTask 注意连接状态管理
页面跳转 wx.navigateTo() 传参用 ?key=value

✅ 以上代码均基于微信小程序最新规范(截至 2025 年),适用于基础库 2.10.0+。实际开发中请替换服务器地址、地图 key 等敏感信息,并做好错误处理与用户提示。

相关推荐
code_YuJun2 小时前
nginx 配置相关
前端·nginx
编程攻城狮3 小时前
第 5 天:C 语言运算符与表达式 —— 数据处理的工具集
c语言·开发语言·学习
对不起初见4 小时前
PlantUML 完整教程:从入门到精通
前端·后端
东方掌管牛马的神4 小时前
oh-my-zsh 配置与使用技巧
前端
你的人类朋友4 小时前
HTTP请求结合HMAC增加安全性
前端·后端·安全
aidingni8884 小时前
掌握 TCJS 游戏摄像系统:打造动态影院级体验
前端·javascript
有梦想的攻城狮4 小时前
从0开始学vue:npm命令详解
前端·vue.js·npm
-一杯为品-5 小时前
【强化学习】#8 DQN(深度Q学习)
学习