【实战教程】基于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/

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