Files
hzdyjs/.cursor/cursorrules-mobile.md
T
zlwu 28232d5d46 feat: 移动端开发规范重大更新
- 🔥 完全重写 .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提供准确的移动端开发上下文,确保生成代码完全符合实际项目架构。
2025-07-04 15:51:33 +08:00

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. ✅ 最佳实践总结

代码规范

  1. 文件组织: 按功能模块组织文件结构
  2. 组件复用: 提取通用组件,避免重复代码
  3. 样式管理: 使用 CSS 变量系统,便于主题切换
  4. 性能优化: 合理使用缓存和懒加载
  5. 用户体验: 添加加载状态、错误处理和无障碍支持

开发流程

  1. 需求分析 → 确定页面结构和功能
  2. 组件设计 → 拆分可复用组件
  3. 页面开发 → 按模板编写页面代码
  4. 样式调优 → 使用统一的设计规范
  5. 功能测试 → 多平台测试确保兼容性
  6. 性能优化 → 优化加载速度和用户体验

质量保证

  1. 代码审查: 确保代码符合规范
  2. 功能测试: 确保所有功能正常工作
  3. 兼容性测试: 确保多平台兼容
  4. 性能测试: 确保应用性能满足要求
  5. 用户体验测试: 确保交互流畅自然

🎯 总结

本规范基于实际的 Vue 3 + uniapp + uview-plus 项目制定,提供了完整的现代化移动端开发流程。

✨ 技术特色:

  • ✅ Vue 3: 现代化的响应式框架
  • ✅ uview-plus: 成熟的 Vue 3 UI 组件库
  • ✅ 现代 CSS: 使用 CSS 变量的设计系统
  • ✅ 无障碍访问: 完整的无障碍访问支持
  • ✅ 智能缓存: 高效的数据缓存策略
  • ✅ 用户体验: 流畅的动画和手势支持

🎨 设计理念:

  • 现代简约的视觉设计
  • 一致的交互体验
  • 响应式适配
  • 无障碍友好

📱 平台支持:

  • H5 (Web)
  • 微信小程序
  • 支付宝小程序
  • iOS/Android App
  • 鸿蒙 App

遵循本规范能够确保代码质量、提升开发效率,并为用户提供优秀的移动端体验。