- Edit
- components/HelloWorld.vue
to test HMR
-
- Check out - create-vue, the official Vue + Vite starter -
-- Learn more about IDE Support for Vue in the - Vue Docs Scaling up Guide. -
-Click on the Vite and Vue logos to learn more
- - - diff --git a/src/dict/index.js b/src/dict/index.js index 327e88d..b9e83fc 100644 --- a/src/dict/index.js +++ b/src/dict/index.js @@ -1,3 +1 @@ -export const sizes = [ - {minWidth:'375px',maxWidth:'768px'}, {minWidth:'768px',maxWidth:'1440px'}, {minWidth:'1440px',maxWidth: '1920px'}, {minWidth:'1920px'} -] +export const sizes = [ {minWidth:'0px',maxWidth:'768px'}, {minWidth:'768px',maxWidth:'1440px'}, {minWidth:'1440px',maxWidth: '1920px'}, {minWidth:'1920px'}] diff --git a/src/main.js b/src/main.js index 92c1e9f..7588280 100644 --- a/src/main.js +++ b/src/main.js @@ -7,5 +7,16 @@ import 'virtual:uno.css' import router from "./router/index.js"; const app = createApp(App); app.use(router); - +app.directive('no-space', { + mounted(el) { + el.addEventListener('input', (e) => { + const originalValue = e.target.value; + const newValue = originalValue.replace(/\s/g, ''); + if (originalValue !== newValue) { + e.target.value = newValue; + e.target.dispatchEvent(new Event('input')); + } + }); + } +}) app.mount('#app'); diff --git a/src/router/index.js b/src/router/index.js index 64d593a..e067d40 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -3,7 +3,7 @@ import { createRouter, createWebHistory } from 'vue-router'; const routes = [ { path: '/', - redirect: 'login' + redirect: 'auth' }, { path: '/login', diff --git a/src/service/index.js b/src/service/index.js new file mode 100644 index 0000000..a511f3c --- /dev/null +++ b/src/service/index.js @@ -0,0 +1,38 @@ +import { useRouter } from 'vue-router'; +import Request from '@/service/request/index.js' +const request = new Request({ + baseURL: import.meta.env.VITE_BASEURL, + timeout: 1000 * 60 * 5, + interceptors: { + //实例的请求拦截器 + requestInterceptors: (config) => { + const token=localStorage.getItem('token') + config.headers['Content-Type'] = config.method === 'get' ? + 'application/x-www-form-urlencoded' : + 'application/json'; + if (config.isFormData) { + config.headers['Content-Type'] = 'multipart/form-data'; + config.headers['Authorization'] = token + } else { + config.headers['Authorization'] = token + } + return config; + }, + //实例的响应拦截器 + responseInterceptors: async (response) => { + if ([200, 201, 204].includes(response.status)) { + return response.config.responseType === 'blob' ? response : response; + } else { + return Promise.reject(new Error(response.data.msg || 'An error occurred.')); + } + } + } +}); +const fontRequest = (config) => { + if (['get', 'GET'].includes(config.method)) { + config.params = config.data; + } + return request.request(config); +}; + +export default fontRequest; diff --git a/src/service/request/index.js b/src/service/request/index.js new file mode 100644 index 0000000..294cd0c --- /dev/null +++ b/src/service/request/index.js @@ -0,0 +1,77 @@ +import axios from 'axios'; +class Request { + // axios 实例 + instance; + // 拦截器对象 + interceptorsObj; + // * 存放取消请求控制器Map + abortControllerMap; + constructor(config) { + this.instance = axios.create(config); + // * 初始化存放取消请求控制器Map + this.abortControllerMap = new Map(); + this.interceptorsObj = config.interceptors; + // 拦截器执行顺序 接口请求 -> 实例请求 -> 全局请求 -> 实例响应 -> 全局响应 -> 接口响应 + this.instance.interceptors.request.use((res) => { + const controller = new AbortController(); + const url = res.url || ''; + res.signal = controller.signal; + this.abortControllerMap.set(url, controller); + return res; + }, (err) => err); + // 使用实例拦截器 + this.instance.interceptors.request.use(this.interceptorsObj?.requestInterceptors, this.interceptorsObj?.requestInterceptorsCatch); + this.instance.interceptors.response.use(this.interceptorsObj?.responseInterceptors, this.interceptorsObj?.responseInterceptorsCatch); + // 全局响应拦截器保证最后执行 + this.instance.interceptors.response.use( + // 因为我们接口的数据都在res.data下,所以我们直接返回res.data + (res) => { + const url = res.config.url || ''; + this.abortControllerMap.delete(url); + return res.data; + }, (err) => err); + } + request(config) { + return new Promise((resolve, reject) => { + // 如果我们为单个请求设置拦截器,这里使用单个请求的拦截器 + if (config.interceptors?.requestInterceptors) { + config = config.interceptors.requestInterceptors(config); + } + this.instance + .request(config) + .then((res) => { + // 如果我们为单个响应设置拦截器,这里使用单个响应的拦截器 + if (config.interceptors?.responseInterceptors) { + res = config.interceptors.responseInterceptors(res); + } + resolve(res); + }) + .catch((err) => { + reject(err); + }); + // .finally(() => {}) + }); + } + /** + * 取消全部请求 + */ + cancelAllRequest() { + for (const [, controller] of this.abortControllerMap) { + controller.abort(); + } + this.abortControllerMap.clear(); + } + /** + * 取消指定的请求 + * @param url 待取消的请求URL + */ + cancelRequest(url) { + const urlList = Array.isArray(url) ? url : [url]; + for (const _url of urlList) { + this.abortControllerMap.get(_url)?.abort(); + this.abortControllerMap.delete(_url); + } + } +} +export default Request; + diff --git a/src/store/auth/index.js b/src/store/auth/index.js new file mode 100644 index 0000000..19e9a51 --- /dev/null +++ b/src/store/auth/index.js @@ -0,0 +1,29 @@ +import {ref} from 'vue' +import {createGlobalState,useStorage} from '@vueuse/core' +import {sendCode} from '@/api/auth/index.js' +import {message} from "@/utils/message.js" +export const useAuth=createGlobalState(()=>{ + const token = useStorage('token', '', localStorage) + const telNum =ref('') + const code=ref('') + const clickSendCode=async ()=>{ + if (!telNum.value){ + message.warning('请输入手机号') + return + } + const data={ + telNum:telNum.value + } + const res=await sendCode(data) + if (res.status===0){ + message.success('发送成功') + } + } + return { + code, + clickSendCode, + telNum, + token + } + +}) diff --git a/src/utils/message.js b/src/utils/message.js new file mode 100644 index 0000000..2c163d1 --- /dev/null +++ b/src/utils/message.js @@ -0,0 +1,5 @@ +import {createDiscreteApi, useMessage} from 'naive-ui' +const { message } = createDiscreteApi( + ["message"] +) +export {message} diff --git a/src/views/confirm/index.vue b/src/views/confirm/index.vue index 69f66bd..254d9d9 100644 --- a/src/views/confirm/index.vue +++ b/src/views/confirm/index.vue @@ -3,14 +3,20 @@ import {useAdaptation} from "@/utils/self-adaption.js"; import {sizes} from "@/dict/index.js"; import size375 from '@/views/confirm/size375/index.vue' import {computed} from "vue"; -const {maxWidth}= useAdaptation(sizes,(maxWidth)=>{ -}) +import size768 from "@/views/confirm/size768/index.vue"; +import size1440 from "@/views/login/size1440/index.vue"; +import size1920 from "@/views/login/size1920/index.vue"; +const {currentRange }= useAdaptation(sizes) const viewComponent = computed(()=>{ - switch (maxWidth.value){ - case '375px': - return size375 - default: + switch (currentRange.value?.minWidth){ + case '0px': return size375 + case '768px': + return size768 + case '1440px': + return size1440 + case '1920px': + return size1920 } }) diff --git a/src/views/confirm/size768/index.vue b/src/views/confirm/size768/index.vue new file mode 100644 index 0000000..0f5f9f8 --- /dev/null +++ b/src/views/confirm/size768/index.vue @@ -0,0 +1,45 @@ + + + +