赞
踩
缘由:由于不经常创建新项目导致每次都忘,在这做个记录,再用的时候就直接翻翻,不用再查了
这里插一句,vite.config.ts 会被多次编辑,不用每次复制,结尾会贴一份完整的代码
路由守卫待续......
可能还有其他也待续......
写了一天写不动了......
npm create vite@latest
npm install element-plus --save
npm install -D unplugin-vue-components unplugin-auto-import
- // vite.config.ts
- 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()],
- + }),
- ],
- })
npm i @types/node scss -D
- // 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 *;
- + 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 *;`,
- + }
- + }
- + }
- })
npm i unocss @unocss/preset-rem-to-px -D
- import { defineConfig, presetUno, presetAttributify } from 'unocss';
- // presetAttributify 属性化模式,属性冲突时,可以通过默认un-前缀来解决:<div m-2 rounded text-teal-400 >代替class</div>
- import presetRemToPx from '@unocss/preset-rem-to-px';
- // 此处我用了rem to px的预设,所以后面不加单位的数字的话会直接被转化为px(如果不用这个预设,就需要用m-100px之类的)
-
- 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'
- }
- });
- 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 *;`,
- }
- }
- }
- })
- import { createApp } from 'vue'
- import './style.css'
- import App from './App.vue'
- + import 'uno.css'
-
- createApp(App).mount('#app')
npm install vue-router@4 -D
- 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
- 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')
- /// <reference types="vite/client" />
-
-
- + declare module "*ts"
- + declare module "*vue"
- const WhiteList = ['/login']; // 配置白名单
- router.beforeEach((to, from, next)=> {
- if (WhiteList.indexOf(to.fullPath) !== -1) { // 判断前往页面是都存在于白名单
- next()
- } else {
- if (localStorage.getItem('userInfo')) {// 判断用户是否d登录
- if (to.name) { // 判断是否存在路由的name名字,如果有则代表有路由表已经存在,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')
- }
- }
- });
- # .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/"
- 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/, '')
- + }
- + }
- + }
- })
npm i axios qs -D
- 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) => {
- // return
- 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) => {
- // status 0: 都显示 1: 不显示loading 2: 不显示报错 3: 都不显示
- 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
- }
pinia-plugin-persistedstate是为了将store存在本地存储中,这样刷新页面关键信息也不会丢失
npm install pinia pinia-plugin-persistedstate -D
- 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");
简单举个例子,创建文件,路径为 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: '', // 用户token
- userInfo: {}, // 用户信息
- }
- },
- persist: {
- storage: sessionStorage, // 这里设置存储方式,也可以是 localStorage
- 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;
- // 调用方法,这里只能把存储里的删掉,pinia本身还需要多加一步$reset()来清除,这个后面有体现
- }
- }
- })
在vue文件中,举个例子,可以结合自己需求去完成
- <script setup lang="ts">
- import { useUserStore } from "@/store/user";
- const userStore: any = useUserStore();
-
-
- onMounted(() => {
- if (!userStore.token) { // 这里直接就能使用
- // 没有登录信息
- router.push({
- name: "login",
- });
- return;
- }
-
- // 这里举个例子怎么使用
-
- // 1. 调用事件去修改
- let token = "xajxbnajsbxjasbxhsbxhsabxjhbsajhbxa";
- userStore.setToken(token);
-
- // 2. 本身自带的方法去修改
- userStore.$patch((state) => {
- state.token = token;
- })
-
- // 3.直接修改不推荐,能不用就不用吧
- userStore.token = token;
- })
-
- const logout = () => {
- // 退出登录
- userStore.$reset(); // 清空本身store中所有数据
- userStore.logout(); // 调用方法
- };
- </script>
pnpm install vite-plugin-zip-pack -D
- 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'
- + import zipPack from "vite-plugin-zip-pack";
-
- export default defineConfig({
- plugins: [
- vue(),
- Unocss({
- configFile: '@/unocss.config.ts'
- }),
- AutoImport({
- resolvers: [ElementPlusResolver()],
- }),
- Components({
- resolvers: [ElementPlusResolver({
- importStyle: 'sass'
- })],
- }),
- + zipPack({
- + inDir: 'xxx', // 输入的文件夹,即要打包的文件夹
- + outDir: './', // 打包好的zip文件放置的位置
- + outFileName: 'xxx.zip', // 打包好的文件名
- + pathPrefix: '' // 可选,文件路径前缀
- + }),
- ],
- 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/, '')
- }
- }
- }
- })
- 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'
- import zipPack from "vite-plugin-zip-pack"
-
- export default defineConfig({
- plugins: [
- vue(),
- Unocss({
- configFile: '@/unocss.config.ts'
- }),
- AutoImport({
- resolvers: [ElementPlusResolver()],
- }),
- Components({
- resolvers: [ElementPlusResolver({
- importStyle: 'sass'
- })],
- }),
- zipPack({
- inDir: 'xxx', // 输入的文件夹,即要打包的文件夹
- outDir: './', // 打包好的zip文件放置的文件夹
- outFileName: 'xxx.zip', // 打包好的文件名
- pathPrefix: '' // 可选,文件路径前缀
- })
- ],
- 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/, '')
- },
- }
- }
- })
- 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");
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。