diff --git a/mock/example/index.ts b/mock/example/index.ts new file mode 100644 index 0000000..d6d6893 --- /dev/null +++ b/mock/example/index.ts @@ -0,0 +1,91 @@ +import Mock from 'mockjs' +import { toAnyString } from '@/utils' + +const List: any[] = [] +const count = 100 + +const baseContent = '

I am testing data, I am testing data.

' +const image_uri = 'https://wpimg.wallstcn.com/e4558086-631c-425c-9430-56ffb46e70b3' + +for (let i = 0; i < count; i++) { + List.push(Mock.mock({ + id: toAnyString(), + timestamp: +Mock.Random.date('T'), + author: '@first', + reviewer: '@first', + title: '@title(5, 10)', + content_short: 'mock data', + content: baseContent, + forecast: '@float(0, 100, 2, 2)', + importance: '@integer(1, 3)', + 'type|1': ['CN', 'US', 'JP', 'EU'], + 'status|1': ['published', 'draft', 'deleted'], + display_time: '@datetime', + comment_disabled: true, + pageviews: '@integer(300, 5000)', + image_uri, + platforms: ['a-platform'] + })) +} + +export default [ + { + url: 'http://mockjs.test.cn/example/list', + type: 'get', + response: (config: any) => { + const { title, pageIndex, pageSize } = config.query + + const mockList = List.filter(item => { + if (title && item.title.indexOf(title) < 0) return false + return true + }) + const pageList = mockList.filter((item, index) => index < pageSize * pageIndex && index >= pageSize * (pageIndex - 1)) + + return { + code: '0000', + data: { + total: mockList.length, + list: pageList + } + } + } + }, + + { + url: 'http://mockjs.test.cn/example/delete', + type: 'post', + response: (config: any) => { + return { + code: '0000', + data: '删除成功' + } + } + }, + + { + url: 'http://mockjs.test.cn/example/detail', + type: 'get', + response: (config: any) => { + const { id } = config.query + for (const example of List) { + if (example.id === id) { + return { + code: '0000', + data: example + } + } + } + } + }, + + { + url: 'http://mockjs.test.cn/example/save', + type: 'post', + response: (config: any) => { + return { + code: '0000', + data: 'success' + } + } + } +] diff --git a/mock/index.ts b/mock/index.ts new file mode 100644 index 0000000..4dda5d7 --- /dev/null +++ b/mock/index.ts @@ -0,0 +1,63 @@ +import Mock from 'mockjs' +import { param2Obj } from '@/utils' + +import example from './example' + +const mocks: any[] = [ + ...example +] + +// for front mock +// please use it cautiously, it will redefine XMLHttpRequest, +// which will cause many of your third-party libraries to be invalidated(like progress event). +export function mockXHR() { + const send: any = (Mock as any).XHR.prototype.send; + ((Mock as any).XHR.prototype as any).proxy_send = send; + (Mock as any).XHR.prototype.send = function() { + if (this.custom.xhr) { + this.custom.xhr.withCredentials = this.withCredentials || false + + if (this.responseType) { + this.custom.xhr.responseType = this.responseType + } + } + this.proxy_send(...arguments) + } + + function XHR2ExpressReqWrap(respond: any) { + return function(options: any) { + let result = null + if (respond instanceof Function) { + const { body, type, url } = options + // https://expressjs.com/en/4x/api.html#req + result = respond({ + method: type, + body: JSON.parse(body), + query: param2Obj(url) + }) + } else { + result = respond + } + return Mock.mock(result) + } + } + + for (const i of mocks) { + Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response)) + } +} + +// for mock server +const responseFake = (url: string, type: string, respond: any) => { + return { + url: new RegExp(`${url}`), + type: type || 'get', + response(req: any, res: any) { + res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond)) + } + } +} + +export default mocks.map(route => { + return responseFake(route.url, route.type, route.response) +}) diff --git a/mock/mock-server.ts b/mock/mock-server.ts new file mode 100644 index 0000000..42fdedb --- /dev/null +++ b/mock/mock-server.ts @@ -0,0 +1,68 @@ +const chokidar = require('chokidar') +const bodyParser = require('body-parser') +const chalk = require('chalk') +const path = require('path') + +const mockDir = path.join(process.cwd(), 'mock') + +function registerRoutes(app) { + let mockLastIndex + const { default: mocks } = require('./index.ts') + for (const mock of mocks) { + app[mock.type](mock.url, mock.response) + mockLastIndex = app._router.stack.length + } + const mockRoutesLength = Object.keys(mocks).length + return { + mockRoutesLength: mockRoutesLength, + mockStartIndex: mockLastIndex - mockRoutesLength + } +} + +function unregisterRoutes() { + Object.keys(require.cache).forEach(i => { + if (i.includes(mockDir)) { + delete require.cache[require.resolve(i)] + } + }) +} + +module.exports = app => { + // es6 polyfill + require('@babel/register') + + // parse app.body + // https://expressjs.com/en/4x/api.html#req.body + app.use(bodyParser.json()) + app.use(bodyParser.urlencoded({ + extended: true + })) + + const mockRoutes = registerRoutes(app) + var mockRoutesLength = mockRoutes.mockRoutesLength + var mockStartIndex = mockRoutes.mockStartIndex + + // watch files, hot reload mock server + chokidar.watch(mockDir, { + ignored: /mock-server/, + ignoreInitial: true + }).on('all', (event, path) => { + if (event === 'change' || event === 'add') { + try { + // remove mock routes stack + app._router.stack.splice(mockStartIndex, mockRoutesLength) + + // clear routes cache + unregisterRoutes() + + const mockRoutes = registerRoutes(app) + mockRoutesLength = mockRoutes.mockRoutesLength + mockStartIndex = mockRoutes.mockStartIndex + + console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed ${path}`)) + } catch (error) { + console.log(chalk.redBright(error)) + } + } + }) +} diff --git a/package.json b/package.json index bf2980e..8afc9c3 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "clipboard": "^2.0.6", "core-js": "^3.6.5", "echarts": "^4.9.0", - "element-plus": "1.0.1-beta.10", + "element-plus": "1.0.1-beta.11", "highlight.js": "^10.4.0", "lodash-es": "^4.17.15", "mockjs": "^1.1.0", diff --git a/src/components/Button/index.vue b/src/components/Button/index.vue deleted file mode 100644 index f4b3ff2..0000000 --- a/src/components/Button/index.vue +++ /dev/null @@ -1,73 +0,0 @@ - - diff --git a/src/components/Editor/props.ts b/src/components/Editor/props.ts index 5bc78c9..c53c1d1 100644 --- a/src/components/Editor/props.ts +++ b/src/components/Editor/props.ts @@ -1,5 +1,5 @@ import { PropType } from 'vue' -import { ElMessage } from 'element-plus' +import { Message } from '_c/Message' import { oneOf } from '@/utils' import { Config } from './types' @@ -18,19 +18,19 @@ export const editorProps = { customAlert: (s: string, t: string) => { switch (t) { case 'success': - ElMessage.success(s) + Message.success(s) break case 'info': - ElMessage.info(s) + Message.info(s) break case 'warning': - ElMessage.warning(s) + Message.warning(s) break case 'error': - ElMessage.error(s) + Message.error(s) break default: - ElMessage.info(s) + Message.info(s) break } }, diff --git a/src/components/Message/index.ts b/src/components/Message/index.ts new file mode 100644 index 0000000..bb56e21 --- /dev/null +++ b/src/components/Message/index.ts @@ -0,0 +1,23 @@ +import { ElMessage } from 'element-plus' + +let messageInstance: any | null = null + +const resetMessage = (options: any) => { + if (messageInstance) { + messageInstance.close() + } + messageInstance = ElMessage(options) +} +['error', 'success', 'info', 'warning'].forEach((type: string) => { + resetMessage[type] = (options: any) => { + if (typeof options === 'string') { + options = { + message: options + } + } + options.type = type + return resetMessage(options) + } +}) + +export const Message = resetMessage as any diff --git a/src/components/Search/index.vue b/src/components/Search/index.vue index cfc2f87..02503b1 100644 --- a/src/components/Search/index.vue +++ b/src/components/Search/index.vue @@ -22,7 +22,7 @@ @@ -30,7 +30,7 @@ @@ -38,7 +38,7 @@