coding-standards.mdc 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. ---
  2. alwaysApply: false
  3. ---
  4. ### 编码规范
  5. #### 命名规范
  6. **文件命名**
  7. - 页面文件:使用 kebab-case,如 `order-list.vue`
  8. - 组件文件:使用 PascalCase,如 `UserCard.vue`
  9. - 工具文件:使用 camelCase,如 `dateUtils.js`
  10. **变量命名**
  11. - 常量:使用 SCREAMING_SNAKE_CASE,如 `API_BASE_URL`
  12. - 变量和函数:使用 camelCase,如 `getUserInfo`
  13. - 组件 props:使用 camelCase,如 `itemList`
  14. - CSS 类名:使用 kebab-case,如 `.user-card`
  15. #### 组件开发规范
  16. **单文件组件结构顺序**
  17. ```vue
  18. <template>
  19. <!-- 模板内容 -->
  20. <view></view>
  21. </template>
  22. <script> // 或 <script setup lang="ts">
  23. export default {
  24. // 组件选项
  25. }
  26. </script>
  27. <style lang="scss" scoped>
  28. /* 样式内容 */
  29. </style>
  30. ```
  31. **Props 定义**
  32. ```javascript
  33. // Vue 2 Options API
  34. props: {
  35. title: {
  36. type: String,
  37. required: true,
  38. default: ''
  39. },
  40. list: {
  41. type: Array,
  42. default: () => []
  43. }
  44. }
  45. ```
  46. #### API 请求规范
  47. **统一请求处理**
  48. ```javascript
  49. // 使用 uni.request 而不是 axios
  50. const request = (options) => {
  51. return new Promise((resolve, reject) => {
  52. uni.request({
  53. url: options.url,
  54. method: options.method || 'GET',
  55. data: options.data || {},
  56. header: {
  57. 'Content-Type': 'application/json',
  58. ...options.header
  59. },
  60. success: (res) => {
  61. if (res.statusCode === 200) {
  62. resolve(res.data)
  63. } else {
  64. reject(res)
  65. }
  66. },
  67. fail: reject
  68. })
  69. })
  70. }
  71. ```
  72. **错误处理**
  73. ```javascript
  74. try {
  75. const result = await apiCall()
  76. // 处理成功结果
  77. } catch (error) {
  78. uni.showToast({
  79. title: error.message || '请求失败',
  80. icon: 'none'
  81. })
  82. }
  83. ```
  84. #### 状态管理规范
  85. **Store 结构**
  86. ```javascript
  87. // Vuex 或 Pinia
  88. const store = {
  89. state: {
  90. user: null,
  91. loading: false
  92. },
  93. mutations: {
  94. SET_USER(state, user) {
  95. state.user = user
  96. },
  97. SET_LOADING(state, loading) {
  98. state.loading = loading
  99. }
  100. },
  101. actions: {
  102. async login({ commit }, params) {
  103. commit('SET_LOADING', true)
  104. try {
  105. const user = await loginApi(params)
  106. commit('SET_USER', user)
  107. } finally {
  108. commit('SET_LOADING', false)
  109. }
  110. }
  111. }
  112. }
  113. ```
  114. #### 样式规范
  115. **使用 rpx 单位**
  116. ```scss
  117. .container {
  118. padding: 32rpx; // 推荐
  119. margin: 16rpx 24rpx; // 推荐
  120. font-size: 28rpx; // 推荐
  121. // 避免使用 px,除非是特殊需求
  122. border: 1px solid #ccc; // 细边框可以使用 px
  123. }
  124. ```
  125. **响应式设计**
  126. ```scss
  127. .grid {
  128. display: flex;
  129. flex-wrap: wrap;
  130. .item {
  131. width: 50%;
  132. // 条件编译样式
  133. /* #ifdef H5 */
  134. &:hover {
  135. background-color: #f5f5f5;
  136. }
  137. /* #endif */
  138. }
  139. }
  140. ```
  141. #### 性能优化规范
  142. **列表渲染优化**
  143. ```vue
  144. <template>
  145. <!-- 使用 key 提升渲染性能 -->
  146. <view v-for="item in list" :key="item.id">
  147. {{ item.name }}
  148. </view>
  149. <!-- 长列表使用虚拟滚动 -->
  150. <recycle-list :list="longList" :item-height="100">
  151. <template v-slot="{ item }">
  152. <ListItem :data="item" />
  153. </template>
  154. </recycle-list>
  155. </template>
  156. ```
  157. **图片优化**
  158. ```vue
  159. <template>
  160. <!-- 使用 lazy-load 懒加载 -->
  161. <image
  162. :src="imageUrl"
  163. mode="aspectFill"
  164. lazy-load
  165. @error="handleImageError"
  166. />
  167. </template>
  168. ```
  169. #### 调试和测试
  170. **调试信息**
  171. ```javascript
  172. // 条件编译调试代码
  173. // #ifdef APP-PLUS || H5
  174. console.log('Debug info:', data)
  175. // #endif
  176. // 使用 uni.getSystemInfo 获取设备信息
  177. uni.getSystemInfo({
  178. success: (res) => {
  179. console.log('Platform:', res.platform)
  180. console.log('Version:', res.version)
  181. }
  182. })
  183. ```
  184. **错误监控**
  185. ```javascript
  186. // App.vue 中的全局错误处理
  187. onError(err => {
  188. console.error('Global error:', err)
  189. // 上报错误到监控平台
  190. })
  191. ```
  192. ### 编码规范
  193. #### 命名规范
  194. **文件命名**
  195. - 页面文件:使用 kebab-case,如 `order-list.vue`
  196. - 组件文件:使用 PascalCase,如 `UserCard.vue`
  197. - 工具文件:使用 camelCase,如 `dateUtils.js`
  198. **变量命名**
  199. - 常量:使用 SCREAMING_SNAKE_CASE,如 `API_BASE_URL`
  200. - 变量和函数:使用 camelCase,如 `getUserInfo`
  201. - 组件 props:使用 camelCase,如 `itemList`
  202. - CSS 类名:使用 kebab-case,如 `.user-card`
  203. #### 组件开发规范
  204. **单文件组件结构顺序**
  205. ```vue
  206. <template>
  207. <!-- 模板内容 -->
  208. </template>
  209. <script>
  210. // 或 <script setup lang="ts">
  211. export default {
  212. // 组件选项
  213. }
  214. </script>
  215. <style lang="scss" scoped>
  216. /* 样式内容 */
  217. </style>
  218. ```
  219. **Props 定义**
  220. ```javascript
  221. // Vue 2 Options API
  222. props: {
  223. title: {
  224. type: String,
  225. required: true,
  226. default: ''
  227. },
  228. list: {
  229. type: Array,
  230. default: () => []
  231. }
  232. }
  233. ```
  234. #### API 请求规范
  235. **统一请求处理**
  236. ```javascript
  237. // 使用 uni.request 而不是 axios
  238. const request = (options) => {
  239. return new Promise((resolve, reject) => {
  240. uni.request({
  241. url: options.url,
  242. method: options.method || 'GET',
  243. data: options.data || {},
  244. header: {
  245. 'Content-Type': 'application/json',
  246. ...options.header
  247. },
  248. success: (res) => {
  249. if (res.statusCode === 200) {
  250. resolve(res.data)
  251. } else {
  252. reject(res)
  253. }
  254. },
  255. fail: reject
  256. })
  257. })
  258. }
  259. ```
  260. **错误处理**
  261. ```javascript
  262. try {
  263. const result = await apiCall()
  264. // 处理成功结果
  265. } catch (error) {
  266. uni.showToast({
  267. title: error.message || '请求失败',
  268. icon: 'none'
  269. })
  270. }
  271. ```
  272. #### 状态管理规范
  273. **Store 结构**
  274. ```javascript
  275. // Vuex 或 Pinia
  276. const store = {
  277. state: {
  278. user: null,
  279. loading: false
  280. },
  281. mutations: {
  282. SET_USER(state, user) {
  283. state.user = user
  284. },
  285. SET_LOADING(state, loading) {
  286. state.loading = loading
  287. }
  288. },
  289. actions: {
  290. async login({ commit }, params) {
  291. commit('SET_LOADING', true)
  292. try {
  293. const user = await loginApi(params)
  294. commit('SET_USER', user)
  295. } finally {
  296. commit('SET_LOADING', false)
  297. }
  298. }
  299. }
  300. }
  301. ```
  302. #### 样式规范
  303. **使用 rpx 单位**
  304. ```scss
  305. .container {
  306. padding: 32rpx; // 推荐
  307. margin: 16rpx 24rpx; // 推荐
  308. font-size: 28rpx; // 推荐
  309. // 避免使用 px,除非是特殊需求
  310. border: 1px solid #ccc; // 细边框可以使用 px
  311. }
  312. ```
  313. **响应式设计**
  314. ```scss
  315. .grid {
  316. display: flex;
  317. flex-wrap: wrap;
  318. .item {
  319. width: 50%;
  320. // 条件编译样式
  321. /* #ifdef H5 */
  322. &:hover {
  323. background-color: #f5f5f5;
  324. }
  325. /* #endif */
  326. }
  327. }
  328. ```
  329. #### 性能优化规范
  330. **列表渲染优化**
  331. ```vue
  332. <template>
  333. <!-- 使用 key 提升渲染性能 -->
  334. <view v-for="item in list" :key="item.id">
  335. {{ item.name }}
  336. </view>
  337. <!-- 长列表使用虚拟滚动 -->
  338. <recycle-list :list="longList" :item-height="100">
  339. <template v-slot="{ item }">
  340. <ListItem :data="item" />
  341. </template>
  342. </recycle-list>
  343. </template>
  344. ```
  345. **图片优化**
  346. ```vue
  347. <template>
  348. <!-- 使用 lazy-load 懒加载 -->
  349. <image
  350. :src="imageUrl"
  351. mode="aspectFill"
  352. lazy-load
  353. @error="handleImageError"
  354. />
  355. </template>
  356. ```
  357. #### 调试和测试
  358. **调试信息**
  359. ```javascript
  360. // 条件编译调试代码
  361. // #ifdef APP-PLUS || H5
  362. console.log('Debug info:', data)
  363. // #endif
  364. // 使用 uni.getSystemInfo 获取设备信息
  365. uni.getSystemInfo({
  366. success: (res) => {
  367. console.log('Platform:', res.platform)
  368. console.log('Version:', res.version)
  369. }
  370. })
  371. ```
  372. **错误监控**
  373. ```javascript
  374. // App.vue 中的全局错误处理
  375. onError(err => {
  376. console.error('Global error:', err)
  377. // 上报错误到监控平台
  378. })
  379. ```