feat(mock): Add mock

This commit is contained in:
kailong321200875 2022-01-08 18:38:20 +08:00
parent 357fc44e51
commit 3fc7d4d39a
20 changed files with 354 additions and 67 deletions

View File

@ -0,0 +1,15 @@
import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer'
const modules = import.meta.globEager('./**/*.ts')
const mockModules: any[] = []
Object.keys(modules).forEach((key) => {
if (key.includes('_')) {
return
}
mockModules.push(...modules[key].default)
})
export function setupProdMockServer() {
createProdMockServer(mockModules)
}

51
mock/user/index.ts Normal file
View File

@ -0,0 +1,51 @@
import { config } from '@/config/axios'
import { MockMethod } from 'vite-plugin-mock'
const { result_code } = config
const List: {
username: string
password: string
role: string
roleId: string
}[] = [
{
username: 'admin',
password: 'admin',
role: 'admin',
roleId: '1'
},
{
username: 'test',
password: 'test',
role: 'test',
roleId: '2'
}
]
export default [
// 登录接口
{
url: '/user/login',
method: 'post',
response: ({ body }) => {
const data = body
let hasUser = false
for (const user of List) {
if (user.username === data.username && user.password === data.password) {
hasUser = true
return {
code: result_code,
data: user
}
}
}
if (!hasUser) {
return {
code: '500',
message: '账号或密码错误'
}
}
}
}
] as MockMethod[]

View File

@ -29,10 +29,12 @@
"@vueuse/core": "^7.5.1",
"@zxcvbn-ts/core": "^1.2.0",
"animate.css": "^4.1.1",
"axios": "^0.24.0",
"element-plus": "1.3.0-beta.1",
"lodash-es": "^4.17.21",
"mockjs": "^1.1.0",
"pinia": "^2.0.9",
"qs": "^6.10.2",
"vue": "3.2.26",
"vue-i18n": "9.1.9",
"vue-router": "^4.0.12",

View File

@ -17,6 +17,7 @@ specifiers:
'@zxcvbn-ts/core': ^1.2.0
animate.css: ^4.1.1
autoprefixer: ^10.4.1
axios: ^0.24.0
commitizen: ^4.2.4
element-plus: 1.3.0-beta.1
eslint: ^8.6.0
@ -35,6 +36,7 @@ specifiers:
postcss-less: ^5.0.0
prettier: ^2.5.1
pretty-quick: ^3.1.3
qs: ^6.10.2
rimraf: ^3.0.2
stylelint: ^14.2.0
stylelint-config-html: ^1.0.0
@ -63,10 +65,12 @@ dependencies:
'@vueuse/core': registry.npmmirror.com/@vueuse/core/7.5.1_vue@3.2.26
'@zxcvbn-ts/core': registry.npmmirror.com/@zxcvbn-ts/core/1.2.0
animate.css: registry.npmmirror.com/animate.css/4.1.1
axios: registry.npmmirror.com/axios/0.24.0
element-plus: registry.npmmirror.com/element-plus/1.3.0-beta.1_vue@3.2.26
lodash-es: registry.nlark.com/lodash-es/4.17.21
mockjs: registry.npmmirror.com/mockjs/1.1.0
pinia: registry.npmmirror.com/pinia/2.0.9_typescript@4.5.4+vue@3.2.26
qs: registry.npmmirror.com/qs/6.10.2
vue: registry.npmmirror.com/vue/3.2.26
vue-i18n: registry.npmmirror.com/vue-i18n/9.1.9_vue@3.2.26
vue-router: registry.npmmirror.com/vue-router/4.0.12_vue@3.2.26
@ -954,9 +958,8 @@ packages:
name: call-bind
version: 1.0.2
dependencies:
function-bind: registry.nlark.com/function-bind/1.1.1
get-intrinsic: registry.nlark.com/get-intrinsic/1.1.1
dev: true
function-bind: registry.npmmirror.com/function-bind/1.1.1
get-intrinsic: registry.npmmirror.com/get-intrinsic/1.1.1
registry.nlark.com/callsites/3.1.0:
resolution:
@ -1929,7 +1932,7 @@ packages:
{
integrity: sha1-0t5eA0JOcH3BDHQGjd7a5wh0Gyc=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.nlark.com/eslint-utils/download/eslint-utils-2.1.0.tgz
tarball: https://registry.nlark.com/eslint-utils/download/eslint-utils-2.1.0.tgz?cache=0&sync_timestamp=1631600361784&other_urls=https%3A%2F%2Fregistry.nlark.com%2Feslint-utils%2Fdownload%2Feslint-utils-2.1.0.tgz
}
name: eslint-utils
version: 2.1.0
@ -1943,7 +1946,7 @@ packages:
{
integrity: sha1-iuuvrOc0W7M1WdsKHxOh0tSMNnI=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.nlark.com/eslint-utils/download/eslint-utils-3.0.0.tgz
tarball: https://registry.nlark.com/eslint-utils/download/eslint-utils-3.0.0.tgz?cache=0&sync_timestamp=1631600361784&other_urls=https%3A%2F%2Fregistry.nlark.com%2Feslint-utils%2Fdownload%2Feslint-utils-3.0.0.tgz
}
id: registry.nlark.com/eslint-utils/3.0.0
name: eslint-utils
@ -2414,17 +2417,6 @@ packages:
version: 1.0.0
dev: true
registry.nlark.com/function-bind/1.1.1:
resolution:
{
integrity: sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.nlark.com/function-bind/download/function-bind-1.1.1.tgz
}
name: function-bind
version: 1.1.1
dev: true
registry.nlark.com/functional-red-black-tree/1.0.1:
resolution:
{
@ -2460,21 +2452,6 @@ packages:
engines: { node: 6.* || 8.* || >= 10.* }
dev: true
registry.nlark.com/get-intrinsic/1.1.1:
resolution:
{
integrity: sha1-FfWfN2+FXERpY5SPDSTNNje0q8Y=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.nlark.com/get-intrinsic/download/get-intrinsic-1.1.1.tgz
}
name: get-intrinsic
version: 1.1.1
dependencies:
function-bind: registry.nlark.com/function-bind/1.1.1
has: registry.nlark.com/has/1.0.3
has-symbols: registry.nlark.com/has-symbols/1.0.2
dev: true
registry.nlark.com/get-stdin/8.0.0:
resolution:
{
@ -2705,7 +2682,6 @@ packages:
name: has-symbols
version: 1.0.2
engines: { node: '>= 0.4' }
dev: true
registry.nlark.com/has-tostringtag/1.0.0:
resolution:
@ -2791,8 +2767,7 @@ packages:
version: 1.0.3
engines: { node: '>= 0.4.0' }
dependencies:
function-bind: registry.nlark.com/function-bind/1.1.1
dev: true
function-bind: registry.npmmirror.com/function-bind/1.1.1
registry.nlark.com/hash-sum/2.0.0:
resolution:
@ -5306,7 +5281,7 @@ packages:
{
integrity: sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.nlark.com/semver/download/semver-5.7.1.tgz?cache=0&sync_timestamp=1631500167672&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fsemver%2Fdownload%2Fsemver-5.7.1.tgz
tarball: https://registry.nlark.com/semver/download/semver-5.7.1.tgz
}
name: semver
version: 5.7.1
@ -5318,7 +5293,7 @@ packages:
{
integrity: sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.nlark.com/semver/download/semver-6.3.0.tgz?cache=0&sync_timestamp=1631500167672&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fsemver%2Fdownload%2Fsemver-6.3.0.tgz
tarball: https://registry.nlark.com/semver/download/semver-6.3.0.tgz
}
name: semver
version: 6.3.0
@ -5398,6 +5373,21 @@ packages:
engines: { node: '>=8' }
dev: true
registry.nlark.com/side-channel/1.0.4:
resolution:
{
integrity: sha1-785cj9wQTudRslxY1CkAEfpeos8=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.nlark.com/side-channel/download/side-channel-1.0.4.tgz
}
name: side-channel
version: 1.0.4
dependencies:
call-bind: registry.nlark.com/call-bind/1.0.2
get-intrinsic: registry.npmmirror.com/get-intrinsic/1.1.1
object-inspect: registry.npmmirror.com/object-inspect/1.12.0
dev: false
registry.nlark.com/slash/3.0.0:
resolution:
{
@ -8570,11 +8560,26 @@ packages:
name: axios
version: 0.21.4
dependencies:
follow-redirects: registry.npmmirror.com/follow-redirects/1.14.6_debug@4.3.3
follow-redirects: registry.npmmirror.com/follow-redirects/1.14.6
transitivePeerDependencies:
- debug
dev: true
registry.npmmirror.com/axios/0.24.0:
resolution:
{
integrity: sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/axios/download/axios-0.24.0.tgz
}
name: axios
version: 0.24.0
dependencies:
follow-redirects: registry.npmmirror.com/follow-redirects/1.14.6
transitivePeerDependencies:
- debug
dev: false
registry.npmmirror.com/big.js/5.2.2:
resolution:
{
@ -9743,7 +9748,7 @@ packages:
{
integrity: sha1-MOvR73wv3/AcOk8VEESvJfqwUj4=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/eslint-visitor-keys/download/eslint-visitor-keys-1.3.0.tgz
tarball: https://registry.npmmirror.com/eslint-visitor-keys/download/eslint-visitor-keys-1.3.0.tgz?cache=0&sync_timestamp=1636378650851&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Feslint-visitor-keys%2Fdownload%2Feslint-visitor-keys-1.3.0.tgz
}
name: eslint-visitor-keys
version: 1.3.0
@ -9755,7 +9760,7 @@ packages:
{
integrity: sha1-9lMoJZMFknOSyTjtROsKXJsr0wM=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/eslint-visitor-keys/download/eslint-visitor-keys-2.1.0.tgz
tarball: https://registry.npmmirror.com/eslint-visitor-keys/download/eslint-visitor-keys-2.1.0.tgz?cache=0&sync_timestamp=1636378650851&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Feslint-visitor-keys%2Fdownload%2Feslint-visitor-keys-2.1.0.tgz
}
name: eslint-visitor-keys
version: 2.1.0
@ -10091,14 +10096,13 @@ packages:
version: 3.2.4
dev: true
registry.npmmirror.com/follow-redirects/1.14.6_debug@4.3.3:
registry.npmmirror.com/follow-redirects/1.14.6:
resolution:
{
integrity: sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/follow-redirects/download/follow-redirects-1.14.6.tgz
}
id: registry.npmmirror.com/follow-redirects/1.14.6
name: follow-redirects
version: 1.14.6
engines: { node: '>=4.0' }
@ -10107,9 +10111,6 @@ packages:
peerDependenciesMeta:
debug:
optional: true
dependencies:
debug: registry.npmmirror.com/debug/4.3.3
dev: true
registry.npmmirror.com/fraction.js/4.1.2:
resolution:
@ -10137,6 +10138,30 @@ packages:
dev: true
optional: true
registry.npmmirror.com/function-bind/1.1.1:
resolution:
{
integrity: sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/function-bind/download/function-bind-1.1.1.tgz
}
name: function-bind
version: 1.1.1
registry.npmmirror.com/get-intrinsic/1.1.1:
resolution:
{
integrity: sha1-FfWfN2+FXERpY5SPDSTNNje0q8Y=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/get-intrinsic/download/get-intrinsic-1.1.1.tgz
}
name: get-intrinsic
version: 1.1.1
dependencies:
function-bind: registry.npmmirror.com/function-bind/1.1.1
has: registry.nlark.com/has/1.0.3
has-symbols: registry.nlark.com/has-symbols/1.0.2
registry.npmmirror.com/git-raw-commits/2.0.11:
resolution:
{
@ -11025,7 +11050,6 @@ packages:
}
name: object-inspect
version: 1.12.0
dev: true
registry.npmmirror.com/p-map/4.0.0:
resolution:
@ -11322,6 +11346,20 @@ packages:
version: 2.0.0
dev: true
registry.npmmirror.com/qs/6.10.2:
resolution:
{
integrity: sha512-mSIdjzqznWgfd4pMii7sHtaYF8rx8861hBO80SraY5GT0XQibWZWJSid0avzHGkDIZLImux2S5mXO0Hfct2QCw==,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/qs/download/qs-6.10.2.tgz
}
name: qs
version: 6.10.2
engines: { node: '>=0.6' }
dependencies:
side-channel: registry.nlark.com/side-channel/1.0.4
dev: false
registry.npmmirror.com/queue-microtask/1.2.3:
resolution:
{

46
src/config/axios.ts Normal file
View File

@ -0,0 +1,46 @@
const config: {
base_url: {
base: string
dev: string
pro: string
test: string
}
result_code: number | string
default_headers: AxiosHeadersType
request_timeout: number
} = {
/**
* api请求基础路径
*/
base_url: {
// 开发环境接口前缀
base: '',
// 打包开发环境接口前缀
dev: '',
// 打包生产环境接口前缀
pro: '',
// 打包测试环境接口前缀
test: ''
},
/**
*
*/
result_code: '0000',
/**
*
*/
request_timeout: 60000,
/**
*
* application/x-www-form-urlencoded multipart/form-data
*/
default_headers: 'application/json'
}
export { config }

37
src/hooks/web/useAxios.ts Normal file
View File

@ -0,0 +1,37 @@
import { service } from '@/plugins/axios'
import { AxiosPromise } from 'axios'
import { useAppStoreWithOut } from '@/store/modules/app'
import { config } from '@/config/axios'
const appStore = useAppStoreWithOut()
const { default_headers } = config
export function useAxios() {
function request({
url,
method,
params,
data,
headersType,
responseType
}: AxiosConfig): AxiosPromise {
return service({
url: url,
method,
params: appStore.getRequestTime ? { time: new Date().getTime(), ...(params || {}) } : params,
data,
responseType: responseType,
headers: {
'Content-Type': headersType || default_headers
}
})
}
return {
request
}
}

View File

@ -0,0 +1,77 @@
import axios, {
AxiosInstance,
AxiosRequestConfig,
AxiosRequestHeaders,
AxiosResponse,
AxiosError
} from 'axios'
import { ElMessage } from 'element-plus'
import qs from 'qs'
import { config } from '@/config/axios'
const { result_code, base_url } = config
export const PATH_URL = base_url[import.meta.env.VITE_API_BASEPATH as string]
// 创建axios实例
const service: AxiosInstance = axios.create({
baseURL: PATH_URL, // api 的 base_url
timeout: config.request_timeout // 请求超时时间
})
// request拦截器
service.interceptors.request.use(
(config: AxiosRequestConfig) => {
console.log('我进来了吗')
if (
config.method === 'post' &&
(config.headers as AxiosRequestHeaders)['Content-Type'] ===
'application/x-www-form-urlencoded'
) {
config.data = qs.stringify(config.data)
}
// get参数编码
if (config.method === 'get' && config.params) {
let url = config.url as string
url += '?'
const keys = Object.keys(config.params)
for (const key of keys) {
if (config.params[key] !== void 0 && config.params[key] !== null) {
url += `${key}=${encodeURIComponent(config.params[key])}&`
}
}
url = url.substring(0, url.length - 1)
config.params = {}
config.url = url
}
return config
},
(error: AxiosError) => {
// Do something with request error
console.log(error) // for debug
Promise.reject(error)
}
)
// response 拦截器
service.interceptors.response.use(
(response: AxiosResponse<Recordable>) => {
console.log(response)
if (response.data.code === result_code) {
return response.data
} else {
ElMessage.error(response.data.message)
}
},
(error: AxiosError) => {
console.log(error)
console.log('err' + error) // for debug
ElMessage.error(error.message)
return Promise.reject(error)
}
)
export { service }

View File

@ -44,7 +44,7 @@ const prefixCls = getPrefixCls('login')
</TransitionGroup>
</div>
</div>
<div class="flex-1 @2xl:p-30px @xl:p-30px @md:p-30px <md:pt-30px dark:bg-v-dark relative">
<div class="flex-1 p-30px <sm:p-10px dark:bg-v-dark relative">
<div class="flex justify-between items-center text-white @2xl:justify-end @xl:justify-end">
<div class="flex items-center @2xl:hidden @xl:hidden">
<img src="@/assets/imgs/logo.png" alt="" class="w-48px h-48px mr-10px" />

7
src/views/Login/api.ts Normal file
View File

@ -0,0 +1,7 @@
import { useAxios } from '@/hooks/web/useAxios'
const { request } = useAxios()
export const loginApi = ({ data }: AxiosConfig) => {
return request({ url: '/user/login', method: 'post', data })
}

View File

@ -5,6 +5,7 @@ import { useI18n } from '@/hooks/web/useI18n'
import { ElButton, ElCheckbox, ElLink } from 'element-plus'
import { required } from '@/utils/formRules'
import { useForm } from '@/hooks/web/useForm'
import { loginApi } from '../api'
const { t } = useI18n()
@ -87,7 +88,10 @@ async function signIn() {
loading.value = true
const { getFormData } = methods
const formData = await getFormData()
console.log(formData)
const res = await loginApi({
data: formData
})
console.log(res)
loading.value = false
}
}

View File

@ -24,8 +24,8 @@
"@/*": ["src/*"]
},
"types": ["@intlify/vite-plugin-vue-i18n/client", "vite/client", "element-plus/global"],
"typeRoots": ["./node_modules/@types/", "./src/types"]
"typeRoots": ["./node_modules/@types/", "./types"]
},
"include": ["./src/**/*"],
"include": ["src/**/*", "types/**/*.d.ts", "mock/**/*.ts"],
"exclude": ["dist", "node_modules"]
}

View File

@ -15,3 +15,17 @@ declare type Recordable<T = any, K = string> = Record<K extends null | undefined
declare type ComponentRef<T> = InstanceType<T>
declare type LocaleType = 'zh-CN' | 'en'
declare type AxiosConfig = {
params?: Recordable
data?: Recordable
url?: string
method?: 'get' | 'post' | 'delete' | 'put'
headersType?: string
responseType?: 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream'
}
declare type AxiosHeadersType =
| 'application/json'
| 'application/x-www-form-urlencoded'
| 'multipart/form-data'

View File

@ -21,8 +21,10 @@ function pathResolve(dir: string) {
// https://vitejs.dev/config/
export default ({ command, mode }: ConfigEnv): UserConfig => {
let env = null
if (command === 'serve') {
env = loadEnv(process.argv[3], root)
const isBuild = command === 'build'
console.log(isBuild)
if (!isBuild) {
env = loadEnv((process.argv[3] === '--mode' ? process.argv[4] : process.argv[3]), root)
} else {
env = loadEnv(mode, root)
}
@ -60,8 +62,8 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
viteMockServe({
ignore: /^\_/,
mockPath: 'mock',
localEnabled: !(command === 'serve'),
prodEnabled: command !== 'serve',
localEnabled: !isBuild,
prodEnabled: isBuild,
injectCode: `
import { setupProdMockServer } from '../mock/_createProductionServer'
@ -105,20 +107,12 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
},
server: {
proxy: {
// 字符串简写写法
'/foo': 'http://localhost:4567/foo',
// 选项写法
'/api': {
target: 'http://jsonplaceholder.typicode.com',
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '')
},
// 正则表达式写法
'^/fallback/.*': {
target: 'http://jsonplaceholder.typicode.com',
changeOrigin: true,
rewrite: path => path.replace(/^\/fallback/, '')
}
// '/api': {
// target: 'http://localhost:3000',
// changeOrigin: true,
// rewrite: path => path.replace(/^\/api/, '')
// }
},
hmr: {
overlay: false
@ -132,7 +126,9 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
'element-plus/lib/locale/lang/zh-cn',
'element-plus/lib/locale/lang/en',
'@iconify/iconify',
'@vueuse/core'
'@vueuse/core',
'axios',
'qs'
]
}
}