【实战教程】基于Vue3+UniApp的拼音学习系统开发


前言

最近完成了一个拼音学习系统的开发,项目采用Vue3+UniApp开发,实现了拼音声调练习、听写练习等功能。通过这个项目,我深入学习了UniApp跨端开发、音频处理、性能优化等技术要点,积累了不少实战经验。在此分享项目开发过程中的一些心得,希望能帮助到有类似需求的开发者。


在线演示

演示地址: http://demo.xiyueta.com/case/web20250218001/

测试账号: demo

测试密码: 123456


系统演示


项目概述

本项目是一个基于Vue3+UniApp开发的拼音学习系统,采用ASP+SQL Server搭建后端服务。系统提供声调练习和听写练习两种模式,支持自定义练习内容。通过游戏化的学习方式提高学习趣味性,并支持H5/小程序/App多端部署,让学习不再受限于设备和场景。


数据库设计


1. 用户表 (pre20250219_user)

CREATE TABLE pre20250219_user (
    user_id INT IDENTITY(1,1) PRIMARY KEY,
    username NVARCHAR(50) NOT NULL UNIQUE,     -- 用户名
    password NVARCHAR(32) NOT NULL,            -- 密码(MD5加密)
    nickname NVARCHAR(50) NOT NULL,            -- 昵称
    email NVARCHAR(100) NOT NULL UNIQUE,       -- 邮箱
    role TINYINT NOT NULL DEFAULT 3,          -- 角色:1超级管理员,2管理员,3普通用户
    token NVARCHAR(32),                        -- 登录token
    token_expire DATETIME,                     -- token过期时间
    coins INT DEFAULT 0,                       -- 用户当前金币数
    last_login_date DATETIME DEFAULT GETDATE(), -- 最后登录日期
    status TINYINT DEFAULT 1,                 -- 状态:1启用,0禁用
    create_time DATETIME DEFAULT GETDATE(),    -- 创建时间
    update_time DATETIME DEFAULT GETDATE()     -- 更新时间
)

-- 插入测试数据 (密码都是123456的MD5加密: 14e1b600b1fd579f47433b88e8d85291)
INSERT INTO pre20250219_user (username, password, nickname, email, role, status) VALUES 
('admin', '14e1b600b1fd579f47433b88e8d85291', '小孙', 'admin@xiyueta.com', 1, 1),
('test', '14e1b600b1fd579f47433b88e8d85291', '小张', 'test@xiyueta.com', 2, 0),
('demo', '14e1b600b1fd579f47433b88e8d85291', '小红', 'demo@xiyueta.com', 3, 1);

2. 金币变更记录表 (pre20250219_coin_transaction)

CREATE TABLE pre20250219_coin_transaction (
    transaction_id INT IDENTITY(1,1) PRIMARY KEY,
    user_id INT NOT NULL,
    change_amount INT NOT NULL,                -- 金币变更数量
    change_type TINYINT NOT NULL,             -- 变更类型
    balance INT NOT NULL,                      -- 变更后的余额
    remark NVARCHAR(200),                      -- 变更备注
    operator_id INT,                          -- 操作人ID
    status TINYINT DEFAULT 1,                 -- 状态
    create_time DATETIME DEFAULT GETDATE(),    -- 创建时间
    update_time DATETIME DEFAULT GETDATE()    -- 更新时间 
)

3. 系统配置表 (pre20250219_sys_config)

CREATE TABLE pre20250219_sys_config (
    config_id INT IDENTITY(1,1) PRIMARY KEY,
    config_key NVARCHAR(50) NOT NULL UNIQUE,   -- 配置键
    config_value NVARCHAR(200) NOT NULL,       -- 配置值
    config_desc NVARCHAR(200),                 -- 配置说明
    status TINYINT DEFAULT 1,                 -- 状态
    create_time DATETIME DEFAULT GETDATE(),    -- 创建时间
    update_time DATETIME DEFAULT GETDATE()     -- 更新时间
)

-- 插入默认配置
INSERT INTO pre20250219_sys_config (config_key, config_value, config_desc) VALUES
('daily_reward', '100', '每日登录奖励金币数'),
('audio_cost', '2', '播放音频消耗金币数'),
('token_expire_hours', '24', 'Token过期小时数'),
('register', '1000', '新用户注册')

4 系统日志表(pre20250219_log)

-- 创建系统日志表
CREATE TABLE pre20250219_log (
    log_id INT IDENTITY(1,1) PRIMARY KEY,
    user_id INT NOT NULL,                     -- 操作用户ID
    username NVARCHAR(50) NOT NULL,            -- 操作用户名
    action NVARCHAR(255) NOT NULL,             -- 操作内容
    ip NVARCHAR(50) NOT NULL,                  -- 操作IP
    create_time DATETIME NOT NULL              -- 操作时间
)

-- 添加默认日志记录
INSERT INTO pre20250219_log (user_id, username, action, ip, create_time) 
VALUES (1, 'admin', '系统初始化', '127.0.0.1', GETDATE())

5. 拼音练习配置表

CREATE TABLE pre20250219_quick_practice_config (
    id INT IDENTITY(1,1) PRIMARY KEY,
    user_id INT NOT NULL,                     -- 用户ID
    title NVARCHAR(50) NOT NULL,                -- 配置标题
    pinyin NVARCHAR(MAX) NOT NULL,             -- 拼音组合
    sort INT DEFAULT 0,                       -- 排序
    create_time DATETIME DEFAULT GETDATE(),     -- 创建时间
    update_time DATETIME DEFAULT GETDATE()     -- 更新时间 
)

6. 快速练习记录表

CREATE TABLE pre20250219_quick_practice_record (
    record_id INT IDENTITY(1,1) PRIMARY KEY,                  -- 记录ID
    user_id INT NOT NULL,                              -- 用户ID
    score INT NOT NULL DEFAULT(0),                     -- 练习得分
    duration INT NOT NULL DEFAULT(0),                  -- 练习时长(秒)
    create_time DATETIME DEFAULT GETDATE(),             -- 创建时间 
)

开发经验分享


1. 跨端兼容性处理

在开发过程中,发现不同平台对音频播放的支持存在差异。H5端可以直接使用Audio对象,但小程序需要使用wx.createInnerAudioContext()。为此,我们封装了统一的音频播放组件,根据平台动态选择实现方式:


const audio = uni.getSystemInfoSync().platform === 'web' 
  ? new Audio() 
  : uni.createInnerAudioContext()

2. 性能优化经验


3. 开发过程中遇到的问题

1. 音频加载失败


2. 页面切换卡顿


3. 数据统计不准


4. 项目亮点

1. 优秀的用户体验


2. 技术亮点


1. 音频播放的跨端处理

// 音频播放器封装
class AudioPlayer {
  constructor() {
    // 根据平台创建音频实例
    this.audio = uni.getSystemInfoSync().platform === 'web' 
      ? new Audio()
      : uni.createInnerAudioContext()
    
    // 统一事件处理
    this.bindEvents()
  }

  bindEvents() {
    if (uni.getSystemInfoSync().platform === 'web') {
      this.audio.onended = () => this.handleEnded()
      this.audio.onerror = () => this.handleError()
    } else {
      this.audio.onEnded(() => this.handleEnded())
      this.audio.onError(() => this.handleError())
    }
  }

  // 播放音频
  play(src) {
    return new Promise((resolve, reject) => {
      try {
        this.audio.src = src
        this.audio.play()
        resolve()
      } catch (err) {
        reject(err)
      }
    })
  }

  // 重试机制
  async playWithRetry(src, maxRetries = 3) {
    for (let i = 0; i < maxRetries; i++) {
      try {
        await this.play(src)
        return
      } catch (err) {
        console.error(`播放失败,第${i + 1}次重试`, err)
        await new Promise(resolve => setTimeout(resolve, 1000))
      }
    }
    throw new Error('音频播放失败')
  }
}

2. 页面切换优化

// app.vue
{
  // 配置需要缓存的页面
  const CACHE_PAGES = ['pages/practice/index']
  
  export default {
    onLaunch() {
      // 预加载频繁访问的页面
      CACHE_PAGES.forEach(path => {
        uni.preloadPage({
          url: path
        })
      })
    }
  }
}

// pages.json
{
  "pages": [{
    "path": "pages/practice/index",
    "style": {
      "navigationBarTitleText": "拼音练习",
      "enablePullDownRefresh": false,
      "disableScroll": true // 禁用滚动提升性能
    }
  }]
}

3. 常见问题及解决方案


3.1 小程序音频问题


3.2 页面数据共享


3.3 样式兼容性


参考资料

1. UniApp官方文档: https://uniapp.dcloud.net.cn/

2. Vue3中文文档: https://cn.vuejs.org/

3. SQL Server文档: https://docs.microsoft.com/sql/

4. ASP Classic教程: https://www.w3schools.com/asp/

5. 拼音教学参考: https://www.edu.cn/


总结

这个项目让我对UniApp跨端开发有了更深的理解,尤其是在音频处理和页面性能优化方面获得了很多实践经验。通过组件化开发和统一状态管理的方式,不仅提高了代码质量,也让项目更容易维护和扩展。希望这些开发经验能给大家一些参考和启发。




关于作者

如果本文章对您有所帮助,欢迎交流和探讨技术问题。

QQ: 313801120

更多文章: www.xiyueta.com/

希望能一起成长,共同探索更多开发技巧!