vue3+ts uniapp小步伐项目搭建

[复制链接]
发表于 2025-6-8 13:13:47 | 显示全部楼层 |阅读模式
1.搭建脚手架
  1. npx degit dcloudio/uni-preset-vue#vite-ts my-uniapp-project
复制代码
2.安装依靠
  1. npm install
复制代码
 3.配置.eslintrc.js、.eslintignore、.prettierrc.js、.prettierignore文件
  1. npm install -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-vue prettier eslint-config-prettier eslint-plugin-prettier
复制代码


  • .eslintrc.js文件
    1. module.exports = {
    2.   root: true,
    3.   env: {
    4.     browser: true,
    5.     node: true,
    6.     es2021: true,
    7.   },
    8.   extends: [
    9.     'plugin:vue/vue3-recommended',
    10.     'eslint:recommended',
    11.     '@vue/typescript/recommended',
    12.     'prettier',
    13.     'plugin:prettier/recommended',
    14.   ],
    15.   parserOptions: {
    16.     ecmaVersion: 2021,
    17.     parser: '@typescript-eslint/parser',
    18.   },
    19.   rules: {
    20.     'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    21.     'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    22.     'vue/multi-word-component-names': 'off',
    23.     '@typescript-eslint/no-explicit-any': 'off',
    24.     '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
    25.     'vue/no-v-html': 'off',
    26.   },
    27. }
    复制代码
  •  .eslintignore文件
    1. node_modules
    2. dist
    3. unpackage
    4. .hbuilderx
    5. .git
    6. *.d.ts
    复制代码
  •  .prettierrc.js文件
    1. {
    2.   "semi": false,
    3.   "singleQuote": true,
    4.   "printWidth": 100,
    5.   "trailingComma": "es5",
    6.   "arrowParens": "avoid",
    7.   "endOfLine": "auto",
    8.   "tabWidth": 2,
    9.   "useTabs": false
    10. }
    复制代码
  •  .prettierignore文件
    1. node_modules
    2. dist
    3. unpackage
    4. .hbuilderx
    5. .git
    6. *.d.ts
    7. package-lock.json
    复制代码
4. 安装sass(编写sass/scss样式)
  1. npm install -D sass sass-loader
复制代码
5.对uni-ui的支持
  1. npm install @dcloudio/uni-ui
复制代码
 6.增长uiapp对ts的支持
  1. npm install @uni-helper/uni-types
复制代码


  • 在tsconfig.json文件中配置 TypeScript 编译器,使其在处理 Vue 文件时可以或许利用 @uni-helper/uni-types/volar-plugin 插件提供的额外支持和增强功能。通过这种方式,开辟者可以得到更精确的类型检查、代码补全和其他相关的开辟体验改进,特别是在利用 UniApp 框架时。 
  1. "vueCompilerOptions": {
  2.         "plugins": [
  3.             "@uni-helper/uni-types/volar-plugin"
  4.         ]
  5.     }
复制代码


  • tsconfigjson 
  1. {
  2.   // "extends": "@vue/tsconfig/tsconfig.json",
  3.   "compilerOptions": {
  4.     "sourceMap": true,
  5.     "module": "ESNext",
  6.     /* Bundler mode */
  7.     "moduleResolution": "Bundler",
  8.     "baseUrl": ".",
  9.     "paths": {
  10.       "@/*": ["./src/*"]
  11.     },
  12.     "lib": ["esnext", "dom"],
  13.     "types": ["@dcloudio/types", "@uni-helper/uni-types"]
  14.   },
  15.   //加入配置,将标签视为原始组件
  16.   "vueCompilerOptions": {
  17.     "plugins": ["@uni-helper/uni-types/volar-plugin"]
  18.   },
  19.   "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
  20. }
复制代码
7.环境配置.env

  1. # Node 运行环境
  2. NODE_ENV=development
  3. # 后端接口地址
  4. VITE_APP_BASE_URL=https://xxx.xxxx.com
  5. # oss资源地址
  6. VITE_APP_OSS_URL=https://xxx.com
  7. # 接口基础地址
  8. VITE_APP_BASE_API=/app-api
  9. # 自定义环境标识
  10. VITE_APP_ENV=development
复制代码
8.配置pinia
  1. npm i pinia
  2. npm i pinia-plugin-persistedstate
复制代码
 



  • store文件夹下index.ts
  1. import { createPinia } from 'pinia'
  2. import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
  3. // 创建 pinia 实例
  4. const pinia = createPinia()
  5. // 使用持久化插件
  6. pinia.use(piniaPluginPersistedstate)
  7. export default pinia
复制代码


  • main.ts配置
  1. import { createSSRApp } from 'vue';
  2. import App from './App.vue';
  3. import pinia from './store';
  4. export function createApp() {
  5.     const app = createSSRApp(App);
  6.     app.use(pinia);
  7.     return {
  8.         app,
  9.     };
  10. }
复制代码


  • 利用以user.ts为实例
  1. import { defineStore } from 'pinia';
  2. import { ref } from 'vue';
  3. import type { UserInfo } from '../types/user';
  4. // 用户状态管理
  5. export const useUserStore = defineStore('user', () => {
  6.     // 用户信息
  7.     const userInfo = ref<UserInfo | null>(null);
  8.     // 登录状态
  9.     const isLoggedIn = ref(false);
  10.     // 设置用户信息
  11.     const setUserInfo = (info: UserInfo | null) => {
  12.         userInfo.value = info;
  13.         isLoggedIn.value = !!info;
  14.         if (info?.token) {
  15.             // 保存到本地存储
  16.             uni.setStorageSync('token', info.token);
  17.         }
  18.     };
  19.     // 清除用户信息
  20.     const clearUserInfo = () => {
  21.         userInfo.value = null;
  22.         isLoggedIn.value = false;
  23.         // 清除本地存储
  24.         uni.removeStorageSync('token');
  25.     };
  26.     // 初始化状态
  27.     const storedToken = uni.getStorageSync('token');
  28.     if (storedToken) {
  29.         isLoggedIn.value = true;
  30.     }
  31.     return {
  32.         userInfo,
  33.         isLoggedIn,
  34.         setUserInfo,
  35.         clearUserInfo,
  36.     };
  37. });
复制代码
9.封装哀求(基于 `luch-request` 封装的同一哀求模块,提供同一的接口调用方式和错误处理机制)



  • request/index.ts
  1. import Request from 'luch-request';
  2. import type { RequestFunction, ErrorResponse, RequestConfig } from './types';
  3. const baseUrl = import.meta.env.VITE_API_BASE_URL;
  4. const baseApi = import.meta.env.VITE_API_BASE_API;
  5. const options = {
  6.     // 显示操作成功消息 默认不显示
  7.     showSuccess: false,
  8.     // 成功提醒 默认使用后端返回值
  9.     successMsg: '',
  10.     // 显示失败消息 默认显示
  11.     showError: true,
  12.     // 失败提醒 默认使用后端返回信息
  13.     errorMsg: '',
  14.     // 显示请求时loading模态框 默认不显示
  15.     showLoading: false,
  16.     // loading提醒文字
  17.     // 需要授权才能请求 默认放开
  18.     auth: false,
  19. };
  20. // 创建请求实例
  21. const httpRequest = new Request({
  22.     baseURL: `${baseUrl}${baseApi}`,
  23.     timeout: 10000,
  24.     header: {
  25.         Accept: 'text/json',
  26.         'Content-Type': 'application/json;charset=UTF-8',
  27.     },
  28.     custom: options,
  29. });
  30. // 请求拦截器
  31. httpRequest.interceptors.request.use(
  32.     config => {
  33.         // 获取登录状态
  34.         const isLoggedIn = !!uni.getStorageSync('token');
  35.         if (config?.custom?.auth && !isLoggedIn) {
  36.             // 未登录,弹出登录弹窗
  37.             return Promise.reject();
  38.         }
  39.         // 在发送请求之前做些什么
  40.         const token = uni.getStorageSync('token');
  41.         if (token) {
  42.             config.header = config.header || {};
  43.             config.header.Authorization = `Bearer ${token}`;
  44.         }
  45.         return config;
  46.     },
  47.     error => {
  48.         return Promise.reject(error);
  49.     },
  50. );
  51. // 响应拦截器
  52. httpRequest.interceptors.response.use(
  53.     response => {
  54.         // 对响应数据做点什么
  55.         return response;
  56.     },
  57.     error => {
  58.         // 处理错误
  59.         const { statusCode, data } = error as ErrorResponse;
  60.         switch (statusCode) {
  61.             case 401:
  62.                 // 未授权,跳转到登录页
  63.                 uni.navigateTo({
  64.                     url: '/pages/login/index',
  65.                 });
  66.                 break;
  67.             case 403:
  68.                 // 权限不足,显示自定义弹窗
  69.                 uni.showModal({
  70.                     title: '提示',
  71.                     content: data.message || '您没有权限执行此操作',
  72.                     showCancel: false,
  73.                 });
  74.                 break;
  75.             case 500:
  76.                 // 服务器错误,显示系统提示
  77.                 uni.showToast({
  78.                     title: '服务器错误,请稍后重试',
  79.                     icon: 'none',
  80.                 });
  81.                 break;
  82.             default:
  83.                 // 其他错误,显示错误信息
  84.                 uni.showToast({
  85.                     title: data.message || '请求失败',
  86.                     icon: 'none',
  87.                 });
  88.         }
  89.         return Promise.reject(error);
  90.     },
  91. );
  92. const request: RequestFunction = config => {
  93.     return httpRequest.middleware(config);
  94. };
  95. export { request };
复制代码


  • request/request.ts
  1. import { RequestInstanceConfig } from './types';
  2. // 请求实例配置
  3. export const requestConfig: RequestInstanceConfig = {
  4.     // 基础URL
  5.     baseURL: import.meta.env.VITE_APP_BASE_API,
  6.     // 超时时间
  7.     timeout: 10000,
  8.     // 请求头
  9.     header: {
  10.         'Content-Type': 'application/json;charset=UTF-8',
  11.     },
  12. };
  13. // 响应状态码
  14. export const ResponseCode = {
  15.     SUCCESS: 200,
  16.     UNAUTHORIZED: 401,
  17.     FORBIDDEN: 403,
  18.     NOT_FOUND: 404,
  19.     SERVER_ERROR: 500,
  20. };
  21. // 响应消息
  22. export const ResponseMessage = {
  23.     SUCCESS: '请求成功',
  24.     UNAUTHORIZED: '未授权,请重新登录',
  25.     FORBIDDEN: '拒绝访问',
  26.     NOT_FOUND: '请求错误,未找到该资源',
  27.     SERVER_ERROR: '服务器错误',
  28.     NETWORK_ERROR: '网络错误,请检查您的网络连接',
  29.     TIMEOUT: '请求超时,请重试',
  30. };
复制代码


  • request/types.ts
  1. import type { HttpRequestConfig, HttpTask, HttpData } from 'luch-request';
  2. // 响应数据基础接口
  3. export interface BaseResponse<T = any> {
  4.     code: number;
  5.     data: T;
  6.     message: string;
  7. }
  8. // 请求配置扩展
  9. export type RequestConfig<T = any> = Omit<HttpRequestConfig<HttpTask>, 'data'> & {
  10.     data?: T extends HttpData ? T : HttpData;
  11. };
  12. // HTTP 请求方法类型
  13. export type HttpMethod =
  14.     | 'GET'
  15.     | 'POST'
  16.     | 'PUT'
  17.     | 'DELETE'
  18.     | 'OPTIONS'
  19.     | 'HEAD'
  20.     | 'TRACE'
  21.     | 'CONNECT';
  22. // 请求函数类型
  23. export type RequestFunction = <T = any, R = any>(
  24.     config: RequestConfig<T>,
  25. ) => Promise<BaseResponse<R>>;
  26. // 错误响应类型
  27. export interface ErrorResponse {
  28.     statusCode: number;
  29.     data: {
  30.         code: number;
  31.         message: string;
  32.     };
  33. }
  34. // 请求实例配置接口
  35. export interface RequestInstanceConfig {
  36.     baseURL: string;
  37.     timeout: number;
  38.     header: Record<string, string>;
  39. }
  40. export interface RequestError {
  41.     statusCode: number;
  42.     data: any;
  43.     config: HttpRequestConfig;
  44.     errMsg: string;
  45. }
  46. export type ErrorMiddleware = (
  47.     error: RequestError,
  48.     next: (error: RequestError) => void,
  49. ) => Promise<void> | void;
  50. // 请求实例类型
复制代码


  • api/user.ts 
  1. import { request } from '@/utils/request';
  2. import type { LoginRequest, LoginResponse } from './types';
  3. // 登录接口
  4. export const login = (data: LoginRequest) => {
  5.   return request<LoginRequest, LoginResponse>({
  6.       url: '/user/login',
  7.       method: 'POST',
  8.       data,
  9.   });
  10. };
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
继续阅读请点击广告

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

© 2001-2025 Discuz! Team. Powered by Discuz! X3.5

GMT+8, 2025-6-27 20:57 , Processed in 0.083947 second(s), 30 queries 手机版|qidao123.com技术社区-IT企服评测▪应用市场 ( 浙ICP备20004199 )|网站地图

快速回复 返回顶部 返回列表