缘由:由于不经常创建新项目导致每次都忘,在这做个记录,再用的时候就直接翻翻,不用再查了
这里插一句,vite.config.ts 会被多次编辑,不用每次复制,结尾会贴一份完整的代码
路由守卫待续......
可能还有其他也待续......
写了一天写不动了......
1.先初始化项目
1.1 选择用vite构建,输入下面命令
复制
1.2 会问你是否继续,直接回车,默认为yes

1.3 输入项目名字

1.4 输入package.json中的名字,不能有大写

1.5 选择你所用的框架,用上下方向键选择,然后回车,我这里用了vue

1.6 选择用什么类型来开发,也是用上下方向键选择,然后回车,我这里用了TypeScript

1.7 然后就创建好了

1.8 然后跟着命令跑起来就行了,这是完整的截图

2.配置UI element-plus(点击这里查看文档)
2.1 先下载UI
| npm install element-plus --save |
复制
2.2 然后配置按需导入
| npm install -D unplugin-vue-components unplugin-auto-import |
复制
| |
| import { defineConfig } from 'vite' |
| import vue from '@vitejs/plugin-vue' |
| +import AutoImport from 'unplugin-auto-import/vite' |
| +import Components from 'unplugin-vue-components/vite' |
| +import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' |
| |
| export default defineConfig({ |
| |
| plugins: [ |
| vue(), |
| + AutoImport({ |
| + resolvers: [ElementPlusResolver()], |
| + }), |
| + Components({ |
| + resolvers: [ElementPlusResolver()], |
| + }), |
| ], |
| }) |
复制
2.3 自定义一个主题
2.3.1 先下载所需要的依赖
| npm i @types/node scss -D |
复制
2.3.2 创建一个scss文件,路径为 src/assets/css/element.scss
| // styles/element/index.scss |
| |
| @forward 'element-plus/theme-chalk/src/common/var.scss' with ( |
| $colors: ( |
| 'primary': ( |
| 'base': #ff7e00, |
| ), |
| ), |
| ); |
| |
| // 如果只是按需导入,则可以忽略以下内容。 |
| // 如果你想导入所有样式: |
| // @use "element-plus/theme-chalk/src/index.scss" as *; |
复制
2.3.3 配置 vite.config.ts ,顺便把@也一起配置了
| + import { fileURLToPath, URL } from 'node:url' |
| import { defineConfig } from 'vite' |
| import vue from '@vitejs/plugin-vue' |
| import AutoImport from 'unplugin-auto-import/vite' |
| import Components from 'unplugin-vue-components/vite' |
| import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' |
| |
| export default defineConfig({ |
| plugins: [ |
| vue(), |
| AutoImport({ |
| resolvers: [ElementPlusResolver()], |
| }), |
| Components({ |
| resolvers: [ElementPlusResolver( |
| + {importStyle: 'sass'} |
| )], |
| }), |
| ], |
| + resolve: { |
| + alias: { |
| + '@': fileURLToPath(new URL('./src', import.meta.url)) |
| + } |
| + }, |
| + css: { |
| + preprocessorOptions: { |
| + scss: { |
| + additionalData: `@use "@/assets/css/element.scss" as *;`, |
| + } |
| + } |
| + } |
| }) |
复制
3.配置unocss(点击这里查看文档)
3.1 下载依赖
| npm i unocss @unocss/preset-rem-to-px -D |
复制
3.2 创建unocss.config.ts
| import { defineConfig, presetUno, presetAttributify } from 'unocss'; |
| |
| import presetRemToPx from '@unocss/preset-rem-to-px'; |
| |
| |
| export default defineConfig({ |
| presets: [presetUno(), presetAttributify(), presetRemToPx({ baseFontSize: 4 })], |
| rules: [ |
| [/^fs-(\d+)$/, ([, num]) => ({ 'font-size': `${num}px` })], |
| [/^lh-(\d+)$/, ([, num]) => ({ 'line-height': `${num}px` })] |
| ], |
| variants: [ |
| matcher => { |
| if (!matcher.startsWith('hover:')) { |
| return matcher; |
| } |
| return { |
| matcher: matcher.slice(6), |
| selector: s => `${s}:hover` |
| }; |
| } |
| ], |
| shortcuts: { |
| 'center': 'flex items-center justify-center' |
| } |
| }); |
复制
3.3 配置 vite.config.ts
| import { fileURLToPath, URL } from 'node:url' |
| import { defineConfig } from 'vite' |
| import vue from '@vitejs/plugin-vue' |
| import AutoImport from 'unplugin-auto-import/vite' |
| import Components from 'unplugin-vue-components/vite' |
| import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' |
| + import Unocss from 'unocss/vite' |
| |
| export default defineConfig({ |
| plugins: [ |
| vue(), |
| + Unocss({ |
| + configFile: '@/unocss.config.ts' |
| + }), |
| AutoImport({ |
| resolvers: [ElementPlusResolver()], |
| }), |
| Components({ |
| resolvers: [ElementPlusResolver({ |
| importStyle: 'sass' |
| })], |
| }), |
| ], |
| resolve: { |
| alias: { |
| '@': fileURLToPath(new URL('./src', import.meta.url)) |
| } |
| }, |
| css: { |
| preprocessorOptions: { |
| scss: { |
| additionalData: `@use "@/assets/css/element.scss" as *;`, |
| } |
| } |
| } |
| }) |
复制
3.4 配置main.ts
| import { createApp } from 'vue' |
| import './style.css' |
| import App from './App.vue' |
| + import 'uno.css' |
| |
| createApp(App).mount('#app') |
复制
4.配置vue-router
4.1 先下载依赖
| npm install vue-router@4 -D |
复制
4.2 在src下创建 router/index.ts
| import { createRouter,createWebHashHistory } from "vue-router"; |
| import login from '@/views/login/login.vue' |
| import home from '@/views/home/home.vue' |
| |
| |
| let routes = [ |
| { |
| path:'/', |
| redirect:'/login' |
| }, |
| { |
| path: '/login', |
| name: 'login', |
| component: login |
| }, |
| { |
| path: '/home', |
| name: 'home', |
| component: home |
| } |
| ] |
| |
| const router = createRouter({ |
| history:createWebHashHistory(), |
| routes |
| }) |
| |
| export default router |
复制
4.3 在 main.ts 中配置
| import { createApp } from 'vue' |
| import './style.css' |
| import App from './App.vue' |
| import 'uno.css' |
| + import router from '@/router/index.ts' |
| |
| |
| - createApp(App).mount('#app') |
| + createApp(App).use(router).mount('#app') |
复制
4.4 如果用了ts报错找不到类型啥的,在根目录下的 vite-env.d.ts 添加下面这个
| |
| |
| |
| + declare module "*ts" |
| + declare module "*vue" |
复制
4.5 路由守卫 路由守卫先待续......
| const WhiteList = ['/login']; |
| router.beforeEach((to, from, next)=> { |
| if (WhiteList.indexOf(to.fullPath) !== -1) { |
| next() |
| } else { |
| if (localStorage.getItem('userInfo')) { |
| if (to.name) { |
| next() |
| } |
| else { |
| let localRoutes: any = localStorage.getItem('routes'); |
| let recursionList = recursionParam(JSON.parse(localRoutes)); |
| for (let item of recursionList) { |
| router.addRoute(item) |
| } |
| next({ ...to, replace: true }) |
| } |
| } else { |
| next('/login') |
| } |
| } |
| }); |
复制
5.配置交互axios
5.1先设置环境变量+代理
5.1.1 根目录下创建.env.production和.env.development
| # .env.development |
| VITE_APP_MODE = "development" |
| #base api |
| VITE_APP_BASE_API = "/aaa/" |
| |
| |
| # .env.production |
| VITE_APP_MODE = "production" |
| #base api |
| VITE_APP_BASE_API = "https://xxx.xxx.com/" |
复制
5.1.2 vite.config.ts 中配置代理
| import { fileURLToPath, URL } from 'node:url' |
| import { defineConfig } from 'vite' |
| import vue from '@vitejs/plugin-vue' |
| import AutoImport from 'unplugin-auto-import/vite' |
| import Components from 'unplugin-vue-components/vite' |
| import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' |
| import Unocss from 'unocss/vite' |
| |
| export default defineConfig({ |
| plugins: [ |
| vue(), |
| Unocss({ |
| configFile: '@/unocss.config.ts' |
| }), |
| AutoImport({ |
| resolvers: [ElementPlusResolver()], |
| }), |
| Components({ |
| resolvers: [ElementPlusResolver({ |
| importStyle: 'sass' |
| })], |
| }), |
| ], |
| resolve: { |
| alias: { |
| '@': fileURLToPath(new URL('./src', import.meta.url)) |
| } |
| }, |
| css: { |
| preprocessorOptions: { |
| scss: { |
| additionalData: `@use "@/assets/css/element.scss" as *;`, |
| } |
| } |
| }, |
| + server: { |
| + proxy: { |
| + |
| + '/xxx': { |
| + target: 'https://xxx.xxx.com/', |
| + changeOrigin: true, |
| + rewrite: (path) => path.replace(/^\/xxx/, '') |
| + } |
| + } |
| + } |
| }) |
复制
5.2 配置axios
5.2.1 先下载axios
复制
5.2.2 在src/utils下创建 api.js 编写 axios 的统一方法
| import axios from "axios" |
| import qs from "qs" |
| import { ElMessage } from 'element-plus' |
| let key = "loading"; |
| |
| const _LOGIN_URL = import.meta.env.VITE_APP_LOGIN_URL; |
| |
| const instance = axios.create({ |
| baseURL: import.meta.env.VITE_APP_BASE_API, |
| timeout: 6000, |
| }); |
| |
| axios.interceptors.response.use((res) => { |
| |
| if (res.status != 200) { |
| ElMessage.error("暂无网络,请稍后重试"); |
| ElMessage.destroy(key); |
| return; |
| } |
| if (!res.data.code || res.config.headers.status == 3) { |
| ElMessage.destroy(key); |
| return res.data; |
| } |
| if (res.data.code == 301) { |
| ElMessage.error("身份已过期,请重新登录"); |
| ElMessage.destroy(key); |
| let expireTime = setTimeout(() => { |
| window.location.href = _LOGIN_URL; |
| clearTimeout(expireTime); |
| }, 3000); |
| return; |
| } |
| if (res.data.code == 313) { |
| ElMessage.error("未登录,请登录"); |
| ElMessage.destroy(key); |
| let notLoginTime = setTimeout(() => { |
| window.location.href = _LOGIN_URL; |
| clearTimeout(notLoginTime); |
| }, 3000); |
| return; |
| } |
| ElMessage.destroy(key); |
| return res.data; |
| }, |
| (error) => { |
| return error; |
| } |
| ); |
| |
| instance.interceptors.request.use((config) => { |
| console.log(config); |
| return config; |
| }, (error) => { |
| |
| return Promise.reject(error); |
| } |
| ); |
| |
| const requestApi = (method, url, params, status, headers) => { |
| |
| if (status != 1 || status != 3) { |
| message.loading({ content: "加载中", key: key, duration: 0 }); |
| } |
| headers.status = status; |
| return new Promise((resolve, reject) => { |
| instance({ |
| method: method, |
| headers: headers, |
| url, |
| params: method == "GET" && params, |
| data: method == "POST" && qs.stringify(params) |
| }).then(res => { |
| resolve(res.data); |
| }).catch(err => { |
| reject(err); |
| }); |
| }) |
| } |
| |
| const login = (params) => requestApi("POST", "/login", params, 0, { "Content-Type": "application/x-www-form-urlencoded" }); |
| |
| export { |
| login |
| } |
复制
6. 配置pinia
6.1 先下载所需的依赖
pinia-plugin-persistedstate是为了将store存在本地存储中,这样刷新页面关键信息也不会丢失
| npm install pinia pinia-plugin-persistedstate -D |
复制
6.2 然后在 main.ts 中配置
| import { createApp } from 'vue' |
| import './style.css' |
| import App from './App.vue' |
| import 'uno.css' |
| import router from '@/router/index.ts' |
| + import { createPinia } from "pinia"; |
| + import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' |
| |
| |
| - createApp(App).use(router).mount('#app') |
| |
| |
| |
| + const app = createApp(App); |
| + const store = createPinia(); |
| + store.use(piniaPluginPersistedstate); |
| |
| + for (const [key, component] of Object.entries(ElementPlusIconsVue)) { |
| + app.component(key, component) |
| + } |
| + app.use(router).use(store).mount("#app"); |
复制
6.3 如何配置
简单举个例子,创建文件,路径为 src/store/user.ts
| import { defineStore } from "pinia" |
| |
| let _LOGIN_URL = import.meta.env.VITE_APP_LOGIN_URL; |
| |
| export const useUserStore = defineStore('user', { |
| state: () => { |
| return { |
| token: '', |
| userInfo: {}, |
| } |
| }, |
| persist: { |
| storage: sessionStorage, |
| paths: ['userInfo', 'token'], |
| }, |
| actions: { |
| setToken(token: string) { |
| this.token = token; |
| }, |
| setUserInfo(userInfo: any) { |
| this.userInfo = userInfo; |
| }, |
| logout() { |
| window.sessionStorage.clear(); |
| window.location.href = _LOGIN_URL; |
| |
| } |
| } |
| }) |
复制
6.4 如何调用操作
在vue文件中,举个例子,可以结合自己需求去完成
| <script setup lang="ts"> |
| import { useUserStore } from "@/store/user"; |
| const userStore: any = useUserStore(); |
| |
| |
| onMounted(() => { |
| if (!userStore.token) { |
| |
| router.push({ |
| name: "login", |
| }); |
| return; |
| } |
| |
| |
| |
| |
| let token = "xajxbnajsbxjasbxhsbxhsabxjhbsajhbxa"; |
| userStore.setToken(token); |
| |
| |
| userStore.$patch((state) => { |
| state.token = token; |
| }) |
| |
| |
| userStore.token = token; |
| }) |
| |
| const logout = () => { |
| |
| userStore.$reset(); |
| userStore.logout(); |
| }; |
| </script> |
复制
7. 结尾
7.1 vite.config.ts
| import { fileURLToPath, URL } from 'node:url' |
| import { defineConfig } from 'vite' |
| import vue from '@vitejs/plugin-vue' |
| import AutoImport from 'unplugin-auto-import/vite' |
| import Components from 'unplugin-vue-components/vite' |
| import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' |
| import Unocss from 'unocss/vite' |
| |
| export default defineConfig({ |
| plugins: [ |
| vue(), |
| Unocss({ |
| configFile: '@/unocss.config.ts' |
| }), |
| AutoImport({ |
| resolvers: [ElementPlusResolver()], |
| }), |
| Components({ |
| resolvers: [ElementPlusResolver({ |
| importStyle: 'sass' |
| })], |
| }), |
| ], |
| resolve: { |
| alias: { |
| '@': fileURLToPath(new URL('./src', import.meta.url)) |
| } |
| }, |
| css: { |
| preprocessorOptions: { |
| scss: { |
| additionalData: `@use "@/assets/css/element.scss" as *;`, |
| } |
| } |
| }, |
| server: { |
| proxy: { |
| |
| '/huipaia': { |
| target: 'https://ai.huipaia.com/', |
| changeOrigin: true, |
| rewrite: (path) => path.replace(/^\/huipaia/, '') |
| }, |
| } |
| } |
| }) |
复制
7.2 main.ts
| import { createApp } from 'vue' |
| import './style.css' |
| import App from './App.vue' |
| import 'uno.css' |
| import router from '@/router/index.ts' |
| import { createPinia } from "pinia"; |
| import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' |
| |
| createApp(App).use(router).mount('#app') |
| |
| const app = createApp(App); |
| const store = createPinia(); |
| store.use(piniaPluginPersistedstate); |
| |
| for (const [key, component] of Object.entries(ElementPlusIconsVue)) { |
| app.component(key, component) |
| } |
| |
| app.use(router).use(store).mount("#app"); |
复制