1.搭建脚手架
- npx degit dcloudio/uni-preset-vue#vite-ts my-uniapp-project
复制代码 2.安装依靠
3.配置.eslintrc.js、.eslintignore、.prettierrc.js、.prettierignore文件
- npm install -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-vue prettier eslint-config-prettier eslint-plugin-prettier
复制代码
- .eslintrc.js文件
- module.exports = {
- root: true,
- env: {
- browser: true,
- node: true,
- es2021: true,
- },
- extends: [
- 'plugin:vue/vue3-recommended',
- 'eslint:recommended',
- '@vue/typescript/recommended',
- 'prettier',
- 'plugin:prettier/recommended',
- ],
- parserOptions: {
- ecmaVersion: 2021,
- parser: '@typescript-eslint/parser',
- },
- rules: {
- 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
- 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
- 'vue/multi-word-component-names': 'off',
- '@typescript-eslint/no-explicit-any': 'off',
- '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
- 'vue/no-v-html': 'off',
- },
- }
复制代码 - .eslintignore文件
- node_modules
- dist
- unpackage
- .hbuilderx
- .git
- *.d.ts
复制代码 - .prettierrc.js文件
- {
- "semi": false,
- "singleQuote": true,
- "printWidth": 100,
- "trailingComma": "es5",
- "arrowParens": "avoid",
- "endOfLine": "auto",
- "tabWidth": 2,
- "useTabs": false
- }
复制代码 - .prettierignore文件
- node_modules
- dist
- unpackage
- .hbuilderx
- .git
- *.d.ts
- package-lock.json
复制代码 4. 安装sass(编写sass/scss样式)
- npm install -D sass sass-loader
复制代码 5.对uni-ui的支持
- npm install @dcloudio/uni-ui
复制代码 6.增长uiapp对ts的支持
- npm install @uni-helper/uni-types
复制代码
- 在tsconfig.json文件中配置 TypeScript 编译器,使其在处理 Vue 文件时可以或许利用 @uni-helper/uni-types/volar-plugin 插件提供的额外支持和增强功能。通过这种方式,开辟者可以得到更精确的类型检查、代码补全和其他相关的开辟体验改进,特别是在利用 UniApp 框架时。
- "vueCompilerOptions": {
- "plugins": [
- "@uni-helper/uni-types/volar-plugin"
- ]
- }
复制代码
- {
- // "extends": "@vue/tsconfig/tsconfig.json",
- "compilerOptions": {
- "sourceMap": true,
- "module": "ESNext",
- /* Bundler mode */
- "moduleResolution": "Bundler",
- "baseUrl": ".",
- "paths": {
- "@/*": ["./src/*"]
- },
- "lib": ["esnext", "dom"],
- "types": ["@dcloudio/types", "@uni-helper/uni-types"]
- },
- //加入配置,将标签视为原始组件
- "vueCompilerOptions": {
- "plugins": ["@uni-helper/uni-types/volar-plugin"]
- },
- "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
- }
复制代码 7.环境配置.env
- # Node 运行环境
- NODE_ENV=development
- # 后端接口地址
- VITE_APP_BASE_URL=https://xxx.xxxx.com
- # oss资源地址
- VITE_APP_OSS_URL=https://xxx.com
- # 接口基础地址
- VITE_APP_BASE_API=/app-api
- # 自定义环境标识
- VITE_APP_ENV=development
复制代码 8.配置pinia
- npm i pinia
- npm i pinia-plugin-persistedstate
复制代码
- import { createPinia } from 'pinia'
- import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
- // 创建 pinia 实例
- const pinia = createPinia()
- // 使用持久化插件
- pinia.use(piniaPluginPersistedstate)
- export default pinia
复制代码
- import { createSSRApp } from 'vue';
- import App from './App.vue';
- import pinia from './store';
- export function createApp() {
- const app = createSSRApp(App);
- app.use(pinia);
- return {
- app,
- };
- }
复制代码
- import { defineStore } from 'pinia';
- import { ref } from 'vue';
- import type { UserInfo } from '../types/user';
- // 用户状态管理
- export const useUserStore = defineStore('user', () => {
- // 用户信息
- const userInfo = ref<UserInfo | null>(null);
- // 登录状态
- const isLoggedIn = ref(false);
- // 设置用户信息
- const setUserInfo = (info: UserInfo | null) => {
- userInfo.value = info;
- isLoggedIn.value = !!info;
- if (info?.token) {
- // 保存到本地存储
- uni.setStorageSync('token', info.token);
- }
- };
- // 清除用户信息
- const clearUserInfo = () => {
- userInfo.value = null;
- isLoggedIn.value = false;
- // 清除本地存储
- uni.removeStorageSync('token');
- };
- // 初始化状态
- const storedToken = uni.getStorageSync('token');
- if (storedToken) {
- isLoggedIn.value = true;
- }
- return {
- userInfo,
- isLoggedIn,
- setUserInfo,
- clearUserInfo,
- };
- });
复制代码 9.封装哀求(基于 `luch-request` 封装的同一哀求模块,提供同一的接口调用方式和错误处理机制)

- import Request from 'luch-request';
- import type { RequestFunction, ErrorResponse, RequestConfig } from './types';
- const baseUrl = import.meta.env.VITE_API_BASE_URL;
- const baseApi = import.meta.env.VITE_API_BASE_API;
- const options = {
- // 显示操作成功消息 默认不显示
- showSuccess: false,
- // 成功提醒 默认使用后端返回值
- successMsg: '',
- // 显示失败消息 默认显示
- showError: true,
- // 失败提醒 默认使用后端返回信息
- errorMsg: '',
- // 显示请求时loading模态框 默认不显示
- showLoading: false,
- // loading提醒文字
- // 需要授权才能请求 默认放开
- auth: false,
- };
- // 创建请求实例
- const httpRequest = new Request({
- baseURL: `${baseUrl}${baseApi}`,
- timeout: 10000,
- header: {
- Accept: 'text/json',
- 'Content-Type': 'application/json;charset=UTF-8',
- },
- custom: options,
- });
- // 请求拦截器
- httpRequest.interceptors.request.use(
- config => {
- // 获取登录状态
- const isLoggedIn = !!uni.getStorageSync('token');
- if (config?.custom?.auth && !isLoggedIn) {
- // 未登录,弹出登录弹窗
- return Promise.reject();
- }
- // 在发送请求之前做些什么
- const token = uni.getStorageSync('token');
- if (token) {
- config.header = config.header || {};
- config.header.Authorization = `Bearer ${token}`;
- }
- return config;
- },
- error => {
- return Promise.reject(error);
- },
- );
- // 响应拦截器
- httpRequest.interceptors.response.use(
- response => {
- // 对响应数据做点什么
- return response;
- },
- error => {
- // 处理错误
- const { statusCode, data } = error as ErrorResponse;
- switch (statusCode) {
- case 401:
- // 未授权,跳转到登录页
- uni.navigateTo({
- url: '/pages/login/index',
- });
- break;
- case 403:
- // 权限不足,显示自定义弹窗
- uni.showModal({
- title: '提示',
- content: data.message || '您没有权限执行此操作',
- showCancel: false,
- });
- break;
- case 500:
- // 服务器错误,显示系统提示
- uni.showToast({
- title: '服务器错误,请稍后重试',
- icon: 'none',
- });
- break;
- default:
- // 其他错误,显示错误信息
- uni.showToast({
- title: data.message || '请求失败',
- icon: 'none',
- });
- }
- return Promise.reject(error);
- },
- );
- const request: RequestFunction = config => {
- return httpRequest.middleware(config);
- };
- export { request };
复制代码
- import { RequestInstanceConfig } from './types';
- // 请求实例配置
- export const requestConfig: RequestInstanceConfig = {
- // 基础URL
- baseURL: import.meta.env.VITE_APP_BASE_API,
- // 超时时间
- timeout: 10000,
- // 请求头
- header: {
- 'Content-Type': 'application/json;charset=UTF-8',
- },
- };
- // 响应状态码
- export const ResponseCode = {
- SUCCESS: 200,
- UNAUTHORIZED: 401,
- FORBIDDEN: 403,
- NOT_FOUND: 404,
- SERVER_ERROR: 500,
- };
- // 响应消息
- export const ResponseMessage = {
- SUCCESS: '请求成功',
- UNAUTHORIZED: '未授权,请重新登录',
- FORBIDDEN: '拒绝访问',
- NOT_FOUND: '请求错误,未找到该资源',
- SERVER_ERROR: '服务器错误',
- NETWORK_ERROR: '网络错误,请检查您的网络连接',
- TIMEOUT: '请求超时,请重试',
- };
复制代码
- import type { HttpRequestConfig, HttpTask, HttpData } from 'luch-request';
- // 响应数据基础接口
- export interface BaseResponse<T = any> {
- code: number;
- data: T;
- message: string;
- }
- // 请求配置扩展
- export type RequestConfig<T = any> = Omit<HttpRequestConfig<HttpTask>, 'data'> & {
- data?: T extends HttpData ? T : HttpData;
- };
- // HTTP 请求方法类型
- export type HttpMethod =
- | 'GET'
- | 'POST'
- | 'PUT'
- | 'DELETE'
- | 'OPTIONS'
- | 'HEAD'
- | 'TRACE'
- | 'CONNECT';
- // 请求函数类型
- export type RequestFunction = <T = any, R = any>(
- config: RequestConfig<T>,
- ) => Promise<BaseResponse<R>>;
- // 错误响应类型
- export interface ErrorResponse {
- statusCode: number;
- data: {
- code: number;
- message: string;
- };
- }
- // 请求实例配置接口
- export interface RequestInstanceConfig {
- baseURL: string;
- timeout: number;
- header: Record<string, string>;
- }
- export interface RequestError {
- statusCode: number;
- data: any;
- config: HttpRequestConfig;
- errMsg: string;
- }
- export type ErrorMiddleware = (
- error: RequestError,
- next: (error: RequestError) => void,
- ) => Promise<void> | void;
- // 请求实例类型
复制代码
- import { request } from '@/utils/request';
- import type { LoginRequest, LoginResponse } from './types';
- // 登录接口
- export const login = (data: LoginRequest) => {
- return request<LoginRequest, LoginResponse>({
- url: '/user/login',
- method: 'POST',
- data,
- });
- };
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
|