vue+vite初始配置和vite获取env环境变量
配置文件
在项目根目录创建两个配置文件
// .env 文件
VITE_PUBLIC_PATH=/demo/
// .env.development 文件
VITE_PUBLIC_PATH=/
VITE_PROXY=https://dingshaohua.cn
node使用环境变量
vite使用配置文件的环境变量如
vite.config.ts
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig(({ command, mode, ssrBuild }) => {
const env = loadEnv(mode, process.cwd());
console.log('env', env);
return {
plugins: [vue()],
base: env.VITE_PUBLIC_PATH,
}
})
参考:
https://cn.vitejs.dev/guide/api-javascript.html#loadenv
https://cn.vitejs.dev/guide/env-and-mode.html#env-variables
如果不想使用 defineConfig,也可以获取环境变量,方法自行百度
vue客户端使用环境变量
如 路由信息使用环境变量
router.ts
const router = createRouter({
history: createWebHashHistory(import.meta.env.BASE_URL),
routes
})
贴一个完成的vite配置
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig(({ command, mode, ssrBuild }) => {
// command 变量其实就可以判断当前的环境变量如: 本地运行是server 还是打包是build
const env = loadEnv(mode, process.cwd());
return {
plugins: [vue()],
base: env.VITE_PUBLIC_PATH, // 解决项目部署服务器二级目录问题(如果你是顶级域名部署 这些可不用做)
server: {
host: true,
proxy: { // 本地开发接口代理 处理本地开发接口跨域问题
'/api': {
target: env.VITE_PROXY,
changeOrigin: true,
ws: true,
secure: false,
// rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
}
})
接口请求 与封装
api.js
import axios from "axios";
import { showFailToast } from "vant";
axios.defaults.baseURL = '/api';
// http response 异常统一处理拦截器
axios.interceptors.response.use(
(response) => {
if (response.data.code === 0) {
return response;
} else {
showFailToast(response.data.msg);
return Promise.reject(response.data);
}
},
(error) => {
return Promise.reject(error.response.data);
}
);
export default {
getXXX() {
return axios.get(`/xxxx`);
},
getYYY(tokenId: any) {
return axios.get(`/xxxx/${tokenId}`);
}
};
使用的时候如下
<script setup lang="ts">
import api from "../../api";
onBeforeMount(() => {
synctXXX();
syncYYY();
});
// 获取基本信息 初始化的时候 回显
const synctWorkOrder = async () => { // 这里如果没有错误的逻辑 可以不用管里 因为全局已经有拦截提示操作
const { data } = await api.getXXX(123);
};
// 提交
const onSubmit = async (values: any) => {
showLoadingToast('提交中...');
try{ // 这里如果没有错误的逻辑
const { data } = await api.getYYY(values);
showSuccessToast("提交成功您已成功提交查询表单,谢谢!");
}catch(e: any){
showFailToast(e.msg || "提交失败,请重新提交");
}
};
</script>
<template>
...
</template>
鉴权拦截
api.js
axios.interceptors.request.use(
(config) => {
if (store.state.token) {
// 判断是否存在token,如果存在的话,则每个http header都加上token
config.headers.Authorization = `token ${store.state.token}`;
}
return config;
},
(err) => {
return Promise.reject(err);
}
);
除了接口处拦截 同时路由守卫也要拦截 这样才完美
// 定义路由的时候就需要多添加一个自定义字段requireAuth,
// 用于判断该路由的访问是否需要登录。如果用户已经登录,则顺利进入路由, 否则就进入登录页面。
const routes = [
{
path: '/',
name: '/',
component: Index
},
{
path: '/repository',
name: 'repository',
meta: {
requireAuth: true, // 添加该字段,表示进入这个路由是需要登录的
},
component: Repository
},
{
path: '/login',
name: 'login',
component: Login
}
];
router.beforeEach((to, from, next) => {
if (to.meta.requireAuth) { // 判断该路由是否需要登录权限
if (store.state.token) { // 通过vuex state获取当前的token是否存在
next();
}
else {
next({
path: '/login',
query: {redirect: to.fullPath} // 将跳转的路由path作为参数,登录成功后跳转到该路由
})
}
}
else {
next();
}
})