- 🔥 完全重写 .cursor/cursorrules-mobile.md (940行) * 基于实际mobile工程Vue 3.4.21+uniapp+uview-plus架构 * 移除所有JeeSite相关内容,精准匹配实际项目 * 新增11个完整章节:技术栈、项目结构、页面开发、组件规范等 - 📚 创建完整规范文档 docs/开发文档/移动端开发规范总结.md (800+行) * 涵盖从项目架构到部署的全流程指导 * 提供可直接使用的页面和组件模板 * 包含现代CSS变量设计系统和用户体验优化 - 🔄 同步更新主配置文件 .cursorrules * 更新移动端技术栈描述 * 调整为Vue 3.4.21+uniapp+uview-plus 3.4.45架构 - 📝 完善变更记录 * 详细记录规范更新背景和技术价值 * 为后续维护提供完整历史记录 核心价值:解决规范与实际项目不匹配问题,为Cursor AI提供准确的移动端开发上下文,确保生成代码完全符合实际项目架构。
22 KiB
22 KiB
Cursor Rules - 移动端开发规范 (Vue 3 + uniapp + uview-plus)
适用范围
- 项目目录:
mobile/(现代化智慧校园移动应用) - 开发语言: JavaScript (Vue 3)
- 平台支持: H5、小程序、APP、鸿蒙
- UI 框架: uView UI 2.x (uview-plus 3.4.45)
智慧校园移动端开发规范
1. 🎯 技术栈规范
核心技术
- 基础框架: uni-app + Vue 3.4.21
- UI 组件库: uview-plus 3.4.45 (Vue 3 版本)
- 开发语言: JavaScript (ES6+)
- 国际化: vue-i18n 9.1.9 (Vue 3 版本)
- 样式预处理: Sass 1.89.2
- 构建工具: Vite 5.2.8
- 代码规范: ESLint 9.30.1
版本信息
{
"name": "uni-preset-vue",
"version": "0.0.0",
"dependencies": {
"@dcloudio/uni-app": "3.0.0-4060620250520001",
"uview-plus": "^3.4.45",
"vue": "^3.4.21",
"vue-i18n": "^9.1.9"
},
"devDependencies": {
"sass": "^1.89.2",
"vite": "5.2.8",
"eslint": "^9.30.1"
}
}
2. 📁 项目结构规范
目录结构
mobile/
├── src/ # 源码目录
│ ├── components/ # 通用组件
│ │ ├── NavBar.vue # 导航栏组件
│ │ ├── Card.vue # 卡片组件
│ │ ├── ServiceItem.vue # 服务项组件
│ │ ├── StatCard.vue # 统计卡片组件
│ │ └── GridLayout.vue # 网格布局组件
│ ├── pages/ # 页面文件
│ │ ├── index/ # 首页
│ │ │ └── index.vue # 首页内容
│ │ ├── workbench/ # 办公中心
│ │ │ └── index.vue # 办公中心内容
│ │ └── profile/ # 我的页面
│ │ └── index.vue # 个人中心内容
│ ├── utils/ # 工具类
│ │ ├── request.js # 网络请求工具
│ │ ├── sse.js # SSE实时数据工具
│ │ ├── device.js # 设备检测工具
│ │ ├── animations.js # 动画工具
│ │ ├── gestures.js # 手势识别工具
│ │ └── accessibility.js # 无障碍访问工具
│ ├── static/ # 静态资源
│ │ ├── tabbar/ # 底部导航图标
│ │ └── fonts/ # 字体文件
│ ├── App.vue # 应用入口
│ ├── main.js # 项目入口
│ ├── pages.json # 页面配置
│ ├── manifest.json # 应用配置
│ └── uni.scss # 全局样式
├── package.json # 项目配置
├── vite.config.js # Vite构建配置
├── eslint.config.cjs # ESLint配置
└── README.md # 项目说明
3. 🎨 页面开发规范
页面模板标准
<template>
<view class="page-container">
<!-- 自定义导航栏 -->
<NavBar
:title="pageTitle"
:show-refresh="true"
:show-search="true"
@refresh="handleRefresh"
@search="handleSearch"
/>
<!-- 主要内容区域 -->
<scroll-view class="main-content" scroll-y enhanced :show-scrollbar="false">
<!-- 页面内容 -->
<view class="content">
<!-- 使用uView-plus组件 -->
<u-cell-group>
<u-cell title="示例项目"></u-cell>
</u-cell-group>
</view>
<!-- 底部间距 -->
<view class="bottom-spacer"></view>
</scroll-view>
</view>
</template>
<script>
import NavBar from '@/components/NavBar.vue';
export default {
name: 'PageName',
components: {
NavBar,
},
data() {
return {
pageTitle: '页面标题',
// 页面数据
};
},
onLoad() {
// 页面加载逻辑
this.initPage();
},
onShow() {
// 页面显示逻辑
},
onUnload() {
// 页面卸载时清理定时器等
if (this.timer) {
clearInterval(this.timer);
}
},
methods: {
initPage() {
// 初始化页面逻辑
},
handleRefresh() {
// 刷新逻辑
uni.showLoading({ title: '刷新中...' });
setTimeout(() => {
uni.hideLoading();
uni.showToast({ title: '刷新成功', icon: 'success' });
}, 1000);
},
handleSearch() {
// 搜索逻辑
},
},
};
</script>
<style lang="scss" scoped>
.page-container {
min-height: 100vh;
background-color: var(--background-color);
display: flex;
flex-direction: column;
}
.main-content {
flex: 1;
padding-bottom: calc(50px + env(safe-area-inset-bottom));
}
.content {
padding: var(--spacing-md);
}
.bottom-spacer {
height: 20px;
}
</style>
页面样式规范
使用 CSS 变量系统
// 主题色彩变量
:root {
--primary-color: rgb(93, 135, 255);
--primary-light: rgba(93, 135, 255, 0.1);
--primary-dark: rgb(73, 115, 235);
--success-color: #52c41a;
--warning-color: #faad14;
--error-color: #ff4d4f;
--text-primary: #262626;
--text-secondary: #595959;
--text-disabled: #bfbfbf;
--border-color: #f0f0f0;
--background-color: #f8f9fa;
--white: #ffffff;
--shadow-light: 0 2px 8px rgba(0, 0, 0, 0.06);
--shadow-medium: 0 4px 16px rgba(0, 0, 0, 0.12);
--radius-small: 4px;
--radius-medium: 8px;
--radius-large: 12px;
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
--spacing-xl: 32px;
--transition-fast: 0.2s ease;
--transition-medium: 0.3s ease;
--font-size-xs: 12px;
--font-size-sm: 14px;
--font-size-md: 16px;
--font-size-lg: 18px;
--font-size-xl: 20px;
}
工具类规范
/* 布局工具类 */
.flex {
display: flex;
}
.flex-center {
display: flex;
align-items: center;
justify-content: center;
}
.flex-between {
display: flex;
align-items: center;
justify-content: space-between;
}
.flex-column {
display: flex;
flex-direction: column;
}
/* 文本工具类 */
.text-center {
text-align: center;
}
.text-primary {
color: var(--primary-color);
}
.text-secondary {
color: var(--text-secondary);
}
/* 背景工具类 */
.bg-primary {
background-color: var(--primary-color);
}
.bg-white {
background-color: var(--white);
}
/* 间距工具类 */
.mt-sm {
margin-top: var(--spacing-sm);
}
.mt-md {
margin-top: var(--spacing-md);
}
.mt-lg {
margin-top: var(--spacing-lg);
}
.p-sm {
padding: var(--spacing-sm);
}
.p-md {
padding: var(--spacing-md);
}
.p-lg {
padding: var(--spacing-lg);
}
4. 🧩 组件开发规范
自定义组件模板
<template>
<view class="component-wrapper" :class="computedClass">
<!-- 组件内容 -->
<slot></slot>
</view>
</template>
<script>
/**
* 智慧校园通用组件
* @property {String} customClass 自定义样式类
* @property {Boolean} disabled 是否禁用
* @example <custom-component :disabled="false">内容</custom-component>
*/
export default {
name: 'CustomComponent',
props: {
customClass: {
type: String,
default: '',
},
disabled: {
type: Boolean,
default: false,
},
},
computed: {
computedClass() {
return {
disabled: this.disabled,
[this.customClass]: !!this.customClass,
};
},
},
methods: {
handleClick() {
if (this.disabled) return;
this.$emit('click');
// 触觉反馈
uni.vibrateShort();
},
},
};
</script>
<style lang="scss" scoped>
.component-wrapper {
// 组件样式
transition: var(--transition-fast);
&.disabled {
opacity: 0.5;
pointer-events: none;
}
}
</style>
组件命名规范
- 文件命名: 使用 PascalCase (如:
NavBar.vue,ServiceItem.vue) - 组件名称: 使用 PascalCase (如:
NavBar,ServiceItem) - 引用方式: 支持驼峰和短横线 (如:
<NavBar>或<nav-bar>)
5. 🌐 API 接口规范
网络请求工具 (utils/request.js)
// API请求配置
const baseURL =
process.env.NODE_ENV === 'development'
? 'http://localhost:3000/api'
: 'https://your-api-domain.com/api';
// 统一请求方法
export const request = (options) => {
return new Promise((resolve, reject) => {
uni.request({
url: baseURL + options.url,
method: options.method || 'GET',
data: options.data || {},
header: {
'Content-Type': 'application/json',
Authorization: getToken(),
...options.header,
},
success: (res) => {
if (res.statusCode === 200) {
resolve(res.data);
} else {
reject(res);
}
},
fail: (error) => {
reject(error);
},
});
});
};
// 获取token
function getToken() {
try {
const token = uni.getStorageSync('token');
return token ? `Bearer ${token}` : '';
} catch (e) {
return '';
}
}
// API方法封装
export const api = {
// 用户登录
login: (data) =>
request({
url: '/auth/login',
method: 'POST',
data,
}),
// 获取用户信息
getUserInfo: () =>
request({
url: '/user/info',
}),
// 获取首页数据
getHomeData: () =>
request({
url: '/home/data',
}),
};
数据缓存规范
// 数据缓存工具 (utils/request.js)
export const storage = {
// 设置缓存
set: (key, value, expire) => {
try {
const data = {
value,
timestamp: Date.now(),
expire: expire ? Date.now() + expire * 1000 : null,
};
uni.setStorageSync(key, JSON.stringify(data));
} catch (e) {
console.error('缓存设置失败:', e);
}
},
// 获取缓存
get: (key) => {
try {
const data = uni.getStorageSync(key);
if (!data) return null;
const parsed = JSON.parse(data);
// 检查是否过期
if (parsed.expire && Date.now() > parsed.expire) {
uni.removeStorageSync(key);
return null;
}
return parsed.value;
} catch (e) {
console.error('缓存获取失败:', e);
return null;
}
},
// 删除缓存
remove: (key) => {
try {
uni.removeStorageSync(key);
} catch (e) {
console.error('缓存删除失败:', e);
}
},
// 清空缓存
clear: () => {
try {
uni.clearStorageSync();
} catch (e) {
console.error('缓存清空失败:', e);
}
},
};
6. 📱 页面配置规范
pages.json 配置
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页",
"navigationStyle": "custom"
}
},
{
"path": "pages/workbench/index",
"style": {
"navigationBarTitleText": "办公中心",
"navigationStyle": "custom"
}
},
{
"path": "pages/profile/index",
"style": {
"navigationBarTitleText": "我的",
"navigationStyle": "custom"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "white",
"navigationBarTitleText": "智慧校园",
"navigationBarBackgroundColor": "rgb(93, 135, 255)",
"backgroundColor": "#f8f9fa"
},
"tabBar": {
"color": "#999999",
"selectedColor": "rgb(93, 135, 255)",
"borderStyle": "white",
"backgroundColor": "#ffffff",
"height": "60px",
"fontSize": "12px",
"iconWidth": "22px",
"iconHeight": "22px",
"list": [
{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "static/tabbar/home.svg",
"selectedIconPath": "static/tabbar/home-active.svg"
},
{
"pagePath": "pages/workbench/index",
"text": "办公中心",
"iconPath": "static/tabbar/workbench.svg",
"selectedIconPath": "static/tabbar/workbench-active.svg"
},
{
"pagePath": "pages/profile/index",
"text": "我的",
"iconPath": "static/tabbar/profile.svg",
"selectedIconPath": "static/tabbar/profile-active.svg"
}
]
}
}
manifest.json 配置
{
"name": "智慧校园",
"appid": "",
"description": "基于Vue3+uniapp的智慧校园移动应用",
"versionName": "1.0.0",
"versionCode": "100",
"transformPx": false,
"vueVersion": "3",
"app-plus": {
"usingComponents": true,
"nvueStyleCompiler": "uni-app",
"compilerVersion": 3,
"splashscreen": {
"alwaysShowBeforeRender": true,
"waiting": true,
"autoclose": true,
"delay": 0
},
"modules": {},
"distribute": {
"android": {
"permissions": [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>"
]
},
"ios": {},
"sdkConfigs": {}
}
},
"quickapp": {},
"mp-weixin": {
"appid": "",
"setting": {
"urlCheck": false
},
"usingComponents": true
},
"mp-alipay": {
"usingComponents": true
},
"mp-baidu": {
"usingComponents": true
},
"mp-toutiao": {
"usingComponents": true
},
"uniStatistics": {
"enable": false
}
}
7. 🎭 用户体验规范
交互设计规范
动画效果使用
// utils/animations.js - 动画工具
export const animationUtils = {
// 淡入动画
fadeIn: (element) => {
element.style.animation = 'fadeIn 0.3s ease';
},
// 滑入动画
slideUp: (element) => {
element.style.animation = 'slideUp 0.3s ease';
},
// 缩放动画
scale: (element) => {
element.style.animation = 'scale 0.2s ease';
},
}
// 在页面中使用
methods: {
handleItemClick() {
// 触觉反馈
uni.vibrateShort();
// 视觉反馈
// 处理点击逻辑
}
}
手势操作支持
// utils/gestures.js - 手势识别
export const gestureManager = {
// 初始化手势
init: (element, callbacks) => {
let startX, startY, startTime;
element.addEventListener('touchstart', (e) => {
startX = e.touches[0].clientX;
startY = e.touches[0].clientY;
startTime = Date.now();
});
element.addEventListener('touchend', (e) => {
const endX = e.changedTouches[0].clientX;
const endY = e.changedTouches[0].clientY;
const endTime = Date.now();
// 判断手势类型
const deltaX = endX - startX;
const deltaY = endY - startY;
const deltaTime = endTime - startTime;
if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > 50) {
if (deltaX > 0) {
callbacks.swipeRight && callbacks.swipeRight();
} else {
callbacks.swipeLeft && callbacks.swipeLeft();
}
}
});
},
};
无障碍访问规范
// utils/accessibility.js - 无障碍访问工具
export const accessibilityUtils = {
// 设置焦点
setFocus: (element) => {
element.focus();
},
// 添加ARIA标签
addAriaLabel: (element, label) => {
element.setAttribute('aria-label', label);
},
// 键盘导航支持
enableKeyboardNavigation: (container) => {
container.addEventListener('keydown', (e) => {
switch (e.key) {
case 'Tab':
// Tab导航逻辑
break;
case 'Enter':
case ' ':
// 激活元素
e.target.click();
break;
case 'Escape':
// 取消操作
break;
}
});
},
};
8. 🚀 性能优化规范
代码优化
组件懒加载
// 页面中使用懒加载
export default {
components: {
// 懒加载组件
LazyComponent: () => import('@/components/LazyComponent.vue'),
},
};
图片优化
<template>
<!-- 响应式图片 -->
<image :src="imageSrc" mode="aspectFit" lazy-load :fade-show="true" @error="handleImageError" />
</template>
<script>
export default {
methods: {
handleImageError() {
// 图片加载失败处理
console.log('图片加载失败');
},
},
};
</script>
网络优化
请求缓存策略
// 智能缓存策略
export const cacheStrategy = {
// 短期缓存 (5分钟)
short: 5 * 60,
// 中期缓存 (30分钟)
medium: 30 * 60,
// 长期缓存 (24小时)
long: 24 * 60 * 60,
};
// API调用示例
export const api = {
getUserInfo: () => {
const cacheKey = 'userInfo';
const cached = storage.get(cacheKey);
if (cached) {
return Promise.resolve(cached);
}
return request({
url: '/user/info',
}).then((data) => {
storage.set(cacheKey, data, cacheStrategy.medium);
return data;
});
},
};
9. 🛠️ 开发工具配置
Vite 配置 (vite.config.js)
import { defineConfig } from 'vite';
import uni from '@dcloudio/vite-plugin-uni';
export default defineConfig({
plugins: [uni()],
server: {
port: 3000,
open: true,
},
build: {
// 生产环境优化
minify: 'terser',
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true,
},
},
},
});
ESLint 配置 (eslint.config.cjs)
module.exports = [
{
files: ['src/**/*.{js,vue}'],
languageOptions: {
ecmaVersion: 2022,
sourceType: 'module',
},
rules: {
indent: ['error', 2],
quotes: ['error', 'single'],
semi: ['error', 'never'],
'no-console': 'warn',
'no-debugger': 'error',
},
},
];
10. 📋 开发命令规范
常用命令
# 安装依赖
npm install
# H5开发
npm run dev:h5
# 微信小程序开发
npm run dev:mp-weixin
# App开发
npm run dev:app
# 构建H5
npm run build:h5
# 构建微信小程序
npm run build:mp-weixin
# 代码检查
npm run lint
# 代码自动修复
npm run lint:fix
11. ✅ 最佳实践总结
代码规范
- 文件组织: 按功能模块组织文件结构
- 组件复用: 提取通用组件,避免重复代码
- 样式管理: 使用 CSS 变量系统,便于主题切换
- 性能优化: 合理使用缓存和懒加载
- 用户体验: 添加加载状态、错误处理和无障碍支持
开发流程
- 需求分析 → 确定页面结构和功能
- 组件设计 → 拆分可复用组件
- 页面开发 → 按模板编写页面代码
- 样式调优 → 使用统一的设计规范
- 功能测试 → 多平台测试确保兼容性
- 性能优化 → 优化加载速度和用户体验
质量保证
- 代码审查: 确保代码符合规范
- 功能测试: 确保所有功能正常工作
- 兼容性测试: 确保多平台兼容
- 性能测试: 确保应用性能满足要求
- 用户体验测试: 确保交互流畅自然
🎯 总结
本规范基于实际的 Vue 3 + uniapp + uview-plus 项目制定,提供了完整的现代化移动端开发流程。
✨ 技术特色:
- ✅ Vue 3: 现代化的响应式框架
- ✅ uview-plus: 成熟的 Vue 3 UI 组件库
- ✅ 现代 CSS: 使用 CSS 变量的设计系统
- ✅ 无障碍访问: 完整的无障碍访问支持
- ✅ 智能缓存: 高效的数据缓存策略
- ✅ 用户体验: 流畅的动画和手势支持
🎨 设计理念:
- 现代简约的视觉设计
- 一致的交互体验
- 响应式适配
- 无障碍友好
📱 平台支持:
- H5 (Web)
- 微信小程序
- 支付宝小程序
- iOS/Android App
- 鸿蒙 App
遵循本规范能够确保代码质量、提升开发效率,并为用户提供优秀的移动端体验。