DEVELOPMENT-GUIDE.md
7.51 KB
开发指南
更新时间: 2026-02-05
本文档提供老来赛项目的开发规范和最佳实践。
🚀 快速开始
1. 环境准备
# 安装依赖
pnpm install
# 启动开发服务器
pnpm run dev:weapp
# 在微信开发者工具中打开 dist/ 目录
2. 开发流程
-
创建新页面:
# 在 src/pages/ 下创建页面目录 mkdir src/pages/YourPage touch src/pages/YourPage/index.vue touch src/pages/YourPage/index.config.js -
注册页面(必须):
// src/app.config.js export default { pages: [ // ... 其他页面 'pages/YourPage/index' ] } -
启动开发:
pnpm run dev:weapp
📝 代码规范
Vue 组件规范
✅ 推荐做法
<script setup>
import { ref, computed } from 'vue'
// 1. Props 定义(有类型和默认值)
const props = defineProps({
userId: {
type: Number,
required: true
},
title: {
type: String,
default: ''
}
})
// 2. Emits 定义(有事件名)
const emit = defineEmits(['update', 'delete'])
// 3. 响应式状态
const loading = ref(false)
const dataList = ref([])
// 4. 计算属性
const totalCount = computed(() => dataList.value.length)
// 5. 方法
const fetchData = async () => {
loading.value = true
try {
const res = await yourAPI()
if (res.code === 1) {
dataList.value = res.data
}
} finally {
loading.value = false
}
}
// 6. 生命周期(使用 Taro Hooks)
import { useLoad, useShow } from '@tarojs/taro'
useLoad((options) => {
// 页面加载(只触发一次)
fetchData()
})
useShow(() => {
// 页面显示(每次显示都触发)
})
</script>
<template>
<view class="page-container">
<!-- 模板内容 -->
</view>
</template>
<style lang="less" scoped>
.page-container {
padding: 30px;
}
</style>
❌ 避免做法
<script setup>
// ❌ 不要在页面中使用 Vue 生命周期
import { onMounted } from 'vue'
onMounted(() => {
// 可能无法正常工作
})
// ❌ 不要直接修改 props
props.title = 'new title'
// ❌ 不要使用 Web API
localStorage.setItem('key', 'value')
API 调用规范
// ✅ 正确 - 检查 res.code === 1
const fetchData = async () => {
try {
const res = await yourAPI()
if (res.code === 1) { // 重要:检查 === 1
// 处理成功
console.log(res.data)
} else {
// 处理业务错误
Taro.showToast({
title: res.msg || '请求失败',
icon: 'none'
})
}
} catch (err) {
// 处理网络错误
console.error('请求失败:', err)
Taro.showToast({
title: '网络异常',
icon: 'none'
})
}
}
// ❌ 错误 - 不检查或错误检查
const fetchData = async () => {
const res = await yourAPI()
if (res.code) { // 错误:应该检查 === 1
// ...
}
}
路径别名使用
// ✅ 正确 - 使用路径别名
import { formatDate } from '@/utils/tools'
import UserCard from '@/components/UserCard.vue'
import { userAPI } from '@/api/user'
// ❌ 错误 - 使用相对路径
import { formatDate } from '../../utils/tools'
import UserCard from '../../components/UserCard.vue'
🎨 样式规范
TailwindCSS + Less 混合使用
<template>
<!-- TailwindCSS 用于布局、间距、颜色(80%) -->
<view class="flex flex-col gap-4 p-4 bg-white">
<text class="text-xl font-bold text-gray-900">标题</text>
</view>
</template>
<style lang="less" scoped>
/* Less 用于组件特定样式(20%) */
.custom-element {
// 深度选择器修改第三方组件
:deep(.nut-popup) {
background-color: #fff;
}
// 复杂动画
@keyframes slide-in {
from { transform: translateX(-100%); }
to { transform: translateX(0); }
}
}
</style>
样式单位
// ✅ 正确 - 使用 px(Taro 自动转换为 rpx)
.container {
width: 100px; // → 100rpx
height: 200px;
}
// ❌ 错误 - 直接写 rpx(除非明确需要)
.container {
width: 100rpx;
}
🔧 常用模式
路由导航
import Taro from '@tarojs/taro'
// 跳转到新页面
Taro.navigateTo({
url: '/pages/Detail/index?id=123'
})
// 重定向(无返回)
Taro.redirectTo({
url: '/pages/Login/index'
})
// 切换 Tab
Taro.switchTab({
url: '/pages/Dashboard/index'
})
// 返回上一页
Taro.navigateBack({
delta: 1
})
获取路由参数
import { useLoad } from '@tarojs/taro'
useLoad((options) => {
const { id, type } = options
console.log('页面参数:', id, type)
})
本地存储
// 异步(推荐)
await Taro.setStorage({ key: 'user', data: userInfo })
const { data } = await Taro.getStorage({ key: 'user' })
// 同步(谨慎使用)
Taro.setStorageSync('token', 'xxxx')
const token = Taro.getStorageSync('token')
提示/弹窗
// Toast
Taro.showToast({
title: '操作成功',
icon: 'success',
duration: 2000
})
// Modal
Taro.showModal({
title: '提示',
content: '确定删除吗?',
success: (res) => {
if (res.confirm) {
// 用户点击确定
}
}
})
🧪 测试规范
单元测试(待添加)
// 示例:工具函数测试
import { describe, it, expect } from 'vitest'
import { formatDate } from '@/utils/tools'
describe('formatDate', () => {
it('should format date correctly', () => {
const result = formatDate('2026-02-05')
expect(result).toBe('2026年02月05日')
})
})
E2E 测试(待添加)
// 示例:关键流程测试
test('should login successfully', async ({ page }) => {
await page.goto('/pages/login/index')
await page.fill('input[name="phone"]', '13800138000')
await page.click('button[type="submit"]')
await expect(page).toHaveURL('/pages/dashboard/index')
})
📦 依赖管理
添加依赖
# 生产依赖
pnpm add package-name
# 开发依赖
pnpm add -D package-name
# NutUI 相关
pnpm add @nutui/nutui-taro
NutUI 组件使用
<template>
<!-- ✅ 正确 - 自动导入,无需手动 import -->
<nut-button type="primary">按钮</nut-button>
<nut-popup v-model:visible="showPopup">
内容
</nut-popup>
</template>
<script setup>
// ❌ 错误 - 不要手动导入
// import { Button } from '@nutui/nutui-taro'
</script>
🚨 常见问题
Q1: 页面不显示?
检查清单:
-
页面是否在
app.config.js中注册 - 页面路径是否正确
- 是否有语法错误
Q2: API 请求失败?
检查清单:
- 域名是否在微信小程序后台配置
- sessionid 是否正确设置
- 请求参数是否正确
- 网络是否正常
Q3: 样式不生效?
检查清单:
-
是否添加了
scoped - 是否使用了不支持的 CSS
- 是否被全局样式覆盖
Q4: 组件不显示?
检查清单:
- 组件名称是否正确(PascalCase)
- NutUI 组件是否正确使用
- 组件路径是否正确
📚 参考资源
项目文档
- CLAUDE.md - 项目指南
- PROJECT-STATUS.md - 项目状态
- CHANGELOG.md - 变更日志
外部资源
维护者: 开发团队 最后更新: 2026-02-05