前言
主要是记录 项目的搭建 大家也可以一起交流学习
后续还准备Nuxt、Vue3、Uniapp、Qiankun、CMS的搭建
不积跬步无以至千里
初始化
node版本为18.20.6
js
npm install -g @vue/cli

使用Vue Cli安装Vue2
js
vue create your_project_name
推荐 www.npmjs.com/package/tre...
可以分析项目结构

进入项目先yarn安装下依赖接下来 yarn serve启动项目

项目启动成功 搭建 Layout 布局 在src文件夹下新建layout文件夹

js
<template>
<div>
<!-- 头部 -->
<header>header</header>
<!-- 路由出口 -->
<!-- https://v2.cn.vuejs.org/v2/api/#transition -->
<transition name="fade" mode="out-in" appear>
<router-view />
</transition>
<!-- 底部 -->
<footer>footer</footer>
</div>
</template>
<script>
export default {
name: 'DefaultLayout',
}
</script>
<style scoped>
.fade-enter {
opacity: 0;
}
/* https://v2.cn.vuejs.org/v2/guide/transitions.html */
.fade-enter-active {
transition: opacity 1s;
}
header,
footer {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
border: 2px dotted #000;
box-sizing: border-box;
}
header {
height: 90px;
}
footer {
height: 60px;
}
</style>
在App.vue中使用

编写第一个路由页面

Layout布局已经生效 但是发现四周有边距 其实是浏览器的默认样式没有清除

先做个准备工作 配置 alias 别名

引入 reset.css 在 App.vue 中使用

最后效果如下

预编译器less的使用
在实际项目开发中,不会使用纯CSS去编写样式,通常使用预编译器以及对应loader提升开发效率
js
npm install -g less
npm install less-loader -D

再进一步 维护全局的通用样式 安装下述依赖
js
npm install style-resources-loader vue-cli-plugin-style-resources-loader --save-dev

env环境变量的使用
在实际开发中,通常有(本地、模拟、测试、生产)多个环境,不同环境中提供不同变量值


VueX使用
推荐模块化 不同板块 放不同的

axios的封装
包含请求重试配置
js
import axios from "axios";
// 创建axios示例
const request = axios.create({
baseURL:
process.env.NODE_ENV === "development"
? "http://localhost:8080"
: process.env.VUE_APP_API_BASE_URL,
timeout: 5000,
withCredentials: true,
});
// 请求拦截器
request.interceptors.request.use(
(config) => {
const token =
typeof window !== "undefined" ? localStorage.getItem("token") : null;
if (token) {
config.headers["Authorization"] = `Bearer ${token}`;
}
return config;
},
(error) => {
// 处理请求错误
console.error("请求错误:", error);
return Promise.reject(error);
}
);
// 响应拦截器
request.interceptors.response.use(
(response) => {
const { data, status } = response;
// 这里可以根据自己的后端接口规范自定义
if (status !== 200) {
console.error("接口请求失败:", data);
// 处理特定错误码
if (response.status === 401) {
// 401: 未授权
// 可以在这里处理登出逻辑
console.error("未授权,请重新登录");
}
return Promise.reject(new Error(data.message || "请求失败"));
}
// 统一包装返回数据格式
if (data.data !== undefined) {
// 如果后端已经包装了data字段,直接返回
return data;
} else {
// 如果后端没有包装data字段,手动包装
return {
code: 200,
data,
message: "success",
success: true,
};
}
},
(error) => {
// 如果是取消请求的错误,直接返回
if (axios.isCancel(error)) {
console.log("请求被取消:", error.message);
return Promise.reject(error);
}
console.error("响应错误:", error);
let message = "请求出错了,请稍后再试";
// 处理请求重试
const config = error.config;
if (config && config.retry && config.retry > 0) {
config.retry--;
const retryDelay = config.retryDelay || 1000;
console.log(
`请求失败,${retryDelay}ms后重试,剩余重试次数:${config.retry}`
);
// 创建新的Promise用于延迟重试
return new Promise((resolve) => {
setTimeout(() => {
resolve(axios(config));
}, retryDelay);
});
}
if (error.response) {
// 请求成功发出且服务器也响应了状态码,但状态代码超出了2xx的范围
switch (error.response.status) {
case 400:
message = "请求错误(400)";
break;
case 401:
message = "未授权,请重新登录(401)";
// 可以在这里处理登出逻辑
break;
case 403:
message = "拒绝访问(403)";
break;
case 404:
message = "请求的资源不存在(404)";
break;
case 500:
message = "服务器错误(500)";
break;
default:
message = `连接出错(${error.response.status})!`;
}
} else if (error.request) {
// 请求已经成功发起,但没有收到响应
message = "网络异常,请检查您的网络连接!";
} else {
// 发送请求时出了点问题
message = error.message;
}
// 可以在这里集成全局的错误提示
console.error(message);
return Promise.reject(error);
}
);
// --------- 通用 API 方法 ---------
export default {
// GET 请求:params -> query string
get(url, params = {}, options = {}) {
return request.get(url, {
params,
retry: options.retry || 0,
retryDelay: options.retryDelay,
headers: {
...options.headers,
},
});
},
// POST 请求:data -> body,支持 JSON、FormData 等
post(url, data = {}, options = {}) {
return request.post(url, data, {
retry: options.retry || 0,
retryDelay: options.retryDelay,
headers: {
"Content-Type": options.contentType || "application/json",
...options.headers,
},
});
},
// DELETE 请求
delete(url, options = {}) {
return request.delete(url, {
retry: options.retry || 0,
retryDelay: options.retryDelay,
headers: {
"Content-Type": options.contentType || "application/json",
...options.headers,
},
});
},
};
项目目录
js
📂 Directory Tree:
├── .browserslistrc
├── .env
├── .env.development
├── .env.production
├── .env.sml
├── .eslintrc.js
├── .gitignore
├── .prettierrc
├── babel.config.js
├── jsconfig.json
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico
│ └── index.html
├── README.md
├── src
│ ├── App.vue
│ ├── assets
│ │ ├── css
│ │ │ ├── common.less // 全局样式
│ │ │ └── reset.css
│ │ └── logo.png
│ ├── components
│ ├── constant
│ │ └── index.js // 常量文件
│ ├── layout
│ │ └── default.vue
│ ├── main.js
│ ├── router
│ │ └── index.js
│ ├── server
│ │ └── index.js
│ ├── service
│ │ └── request.js
│ ├── store
│ │ ├── index.js
│ │ └── modules
│ │ ├── home.js
│ │ └── my.js
│ ├── utils
│ │ └── index.js //工具类函数
│ └── views
│ └── home
│ └── home.vue
├── vue.config.js
└── yarn.lock
以上是一个vue2项目的基础架构,大家可以给出建议,多多向大佬们学习
TODO 国际化