Skip to content

Commit

Permalink
feat: 加上完整示例demo
Browse files Browse the repository at this point in the history
  • Loading branch information
yuntian001 committed Jan 9, 2023
1 parent 816c941 commit 1707f46
Show file tree
Hide file tree
Showing 10 changed files with 732 additions and 6 deletions.
401 changes: 401 additions & 0 deletions mock/apiDemo/demo.ts

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions src/api/api.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export class PageParams {
page = 1;
size = 10;
}

export type PageResult<R> = {
total: number;
list: R[];
};
78 changes: 78 additions & 0 deletions src/api/demo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { request, RequestOptions } from '@/utils/request';
import { bookType } from '@/dict/book';
import { PageParams, PageResult } from './api.model';

const enum Api {
LIST = 'demo',
ADD = 'demo',
UPDATE = 'demo/{id}',
DELETE = 'demo/{id}',
}

export class Info {
id?: number;
name = '';
type: keyof typeof bookType = '1';
bookName = '';
price = 0.0;
section = 0;
createTime?: string;
}

export class ListParams extends PageParams {
name = '';
type?: keyof typeof bookType;
bookName = '';
priceStart?: number;
priceEnd?: number;
sectionStart?: number;
sectionEnd?: number;
createTime?: [string, string];
}

//列表
export function listApi(options: RequestOptions<PageResult<Required<Info>>, [ListParams]> = { noLoading: true }) {
return request(
(params) => ({
url: Api.LIST,
method: 'get',
params,
}),
options,
);
}

//新增
export function addApi(noLoading = true) {
return request<null, [Info]>(
(data) => ({
url: Api.ADD,
method: 'post',
data,
}),
{ noLoading },
);
}

//更新
export function updateApi(noLoading = true) {
return request<null, [number, Info]>(
(id, data) => ({
url: Api.UPDATE.replace('{id}', String(id)),
method: 'put',
data,
}),
{ noLoading },
);
}

//删除
export function delApi(noLoading = true) {
return request<null, [number]>(
(id) => ({
url: Api.DELETE.replace('{id}', String(id)),
method: 'delete',
}),
{ noLoading },
);
}
6 changes: 6 additions & 0 deletions src/dict/book.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const bookType = {
'1': '纸质',
'2': '电脑',
'3': '手机',
'4': '电纸书',
};
14 changes: 9 additions & 5 deletions src/locales/lang/en/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,16 @@
"退出登录": "Logout",
"页面不见了": "The page is gone",
"去": "Go",
"操作失败,请稍后重试":"Operation failed, please try again later",
"返回值解析失败":"Failed to parse the return value",
"请求异常,请联系管理员":"The request is abnormal, Please contact the administrator",
"搜索":"Search",
"操作失败,请稍后重试": "Operation failed, please try again later",
"返回值解析失败": "Failed to parse the return value",
"请求异常,请联系管理员": "The request is abnormal, Please contact the administrator",
"搜索": "Search",
"清除": "Clear",
"内容": "Conent",
"请输入": "Please input",
"获取": "Get"
"获取": "Get",
"收起": "Pack Up ",
"展开": "Expansion",
"查询": "Query",
"操作": "Operate"
}
3 changes: 2 additions & 1 deletion src/locales/lang/en/menu.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@
"角色权限": "Role Permission",
"图片预览": "Image Viewer",
"弹窗": "Dialog",
"筛选表单": "Search form"
"筛选表单": "Search form",
"完整示例": "Complete Example"
}
16 changes: 16 additions & 0 deletions src/router/routes/6-demo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { RouteRecordRaw } from 'vue-router';
import { Layout } from '@/router/constant';
export const routes: RouteRecordRaw[] = [
{
path: '/demo',
component: Layout,
children: [
{
path: 'index',
component: () => import('@/views/demo/demo.vue'),
meta: { title: '完整示例', icon: 'mel-icon-set-up' },
},
],
meta: { title: '完整示例', icon: 'mel-icon-set-up' },
},
];
88 changes: 88 additions & 0 deletions src/views/demo/components/add.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<template>
<me-dialog
:title="t(info.id ? '编辑' : '新增')"
:model-value="modelValue"
:close-on-click-modal="false"
class="add-dialog"
@update:model-value="emit('update:modelValue', $event)"
>
<el-form ref="formEl" :model="info" :rules="rules" class="add">
<el-form-item :label="t('姓名')" prop="name">
<el-input v-model="info.name"></el-input>
</el-form-item>
<el-form-item :label="t('书名')" prop="bookName">
<el-input v-model="info.bookName"></el-input>
</el-form-item>
<el-form-item :label="t('类型')" prop="type">
<el-select v-model="info.type">
<el-option v-for="(item, key) in bookType" :key="key" :value="key" :label="item" />
</el-select>
</el-form-item>
<el-form-item :label="t('价格')" prop="price">
<el-input-number v-model="info.price" :min="0" :precision="2"></el-input-number>
</el-form-item>
<el-form-item :label="t('章节')" prop="section">
<el-input-number v-model="info.section" :min="0" :precision="0"></el-input-number>
</el-form-item>
</el-form>
<template #footer>
<el-button type="primary" :loading="loading" @click="sub()">{{ t('提交') }}</el-button>
<el-button @click="emit('update:modelValue', false)">{{ t('取消') }}</el-button>
</template>
</me-dialog>
</template>

<script setup lang="ts" name="Add">
import { Info, addApi, updateApi } from '@/api/demo';
import { useLocalesI18n } from '@/locales/i18n';
import { bookType } from '@/dict/book';
import { FormInstance, FormRules } from 'element-plus';
let { t } = useLocalesI18n({}, [(locale: string) => import(`../lang/${locale}.json`), 'demo']);
const info = ref(new Info());
const props = defineProps<{
data?: Required<Info>;
modelValue: boolean;
}>();
const emit = defineEmits<{
(e: 'update:modelValue', show: boolean): void;
(e: 'success'): void;
}>();
watch(
() => props.data,
(data) => {
info.value = data ?? new Info();
},
{ immediate: true },
);
const rules: FormRules = {
name: { required: true, message: t('请填写') + t('姓名'), trigger: 'blur' },
bookName: { required: true, message: t('请填写') + t('书名'), trigger: 'blur' },
type: { required: true, message: t('请选择') + t('类型'), trigger: 'blur' },
price: { required: true, message: t('请填写') + t('价格'), trigger: 'blur' },
section: { required: true, message: t('请填写') + t('章节'), trigger: 'blur' },
};
const formEl = ref<FormInstance>();
const loading = ref(false);
const sub = async () => {
loading.value = true;
formEl.value!.validate(async (isValid, invalidFields) => {
if (isValid) {
if (info.value.id) {
await updateApi().runAsync(info.value.id, info.value);
} else {
await addApi().runAsync(info.value);
}
emit('update:modelValue', false);
emit('success');
} else {
formEl.value!.scrollToField(Object.keys(invalidFields!)[0]);
}
loading.value = false;
});
};
</script>
<style lang="scss" scoped>
.add-dialog {
max-height: 60vh;
}
</style>
115 changes: 115 additions & 0 deletions src/views/demo/demo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<template>
<div class="demo">
<el-card>
<me-search-form :model="params" class="search-form" @search="search(1)">
<el-form-item :label="t('姓名')" prop="name">
<el-input v-model="params.name"></el-input>
</el-form-item>
<template #more>
<el-form-item :label="t('类型')" prop="type">
<el-select v-model="params.type">
<el-option v-for="(item, key) in bookType" :key="key" :value="key" :label="item" />
</el-select>
</el-form-item>
<el-form-item :label="t('价格')" prop="priceStart">
<el-input-number v-model="params.priceStart" :min="0" :precision="2"></el-input-number>
&nbsp; - &nbsp;<el-form-item prop="priceEnd">
<el-input-number v-model="params.priceEnd" :min="0" :precision="2"></el-input-number>
</el-form-item>
</el-form-item>
<el-form-item :label="t('章节')" prop="sectionStart">
<el-input-number v-model="params.sectionStart" :min="0" :precision="0"></el-input-number>
&nbsp; - &nbsp;<el-form-item prop="sectionEnd">
<el-input-number v-model="params.sectionEnd" :min="0" :precision="0"></el-input-number>
</el-form-item>
</el-form-item>
<el-form-item :label="t('创建时间')" prop="createTime">
<el-date-picker v-model="params.createTime" type="daterange" value-format="YYYY-MM-DD" />
</el-form-item>
</template>
</me-search-form>
</el-card>
<el-card style="margin-top: 10px">
<me-vxe-table
v-model:quick-search="params.name"
:loading="loading"
:data="data?.list"
:pagination-options="{
currentPage: params.page,
pageSize: params.size,
total: data?.total ?? 0,
layout: 'sizes, prev, pager, next, jumper, ->, total',
change: search,
}"
align="center"
border
@refresh="search(1)"
@add="showAddOrUp()"
@quick-search="search(1)"
>
<vxe-column field="id" :title="t('ID')" min-width="100px"></vxe-column>
<vxe-column field="name" :title="t('姓名')" min-width="100px"></vxe-column>
<vxe-column field="bookName" :title="t('书名')" min-width="150px"></vxe-column>
<vxe-column field="type" :title="t('类型')" min-width="150px">
<template #default="{ row }: { row: Required<Info> }">
{{ bookType[row.type] }}
</template>
</vxe-column>
<vxe-column field="price" :title="t('价格')" min-width="100px"></vxe-column>
<vxe-column field="section" :title="t('章节')" min-width="100px"></vxe-column>
<vxe-column field="createTime" :title="t('创建时间')" min-width="150px"></vxe-column>
<vxe-column :title="t('操作')" fixed="right" min-width="150px">
<template #default="{ row }: { row: Required<Info> }">
<el-button @click="showAddOrUp(row)">
<mel-icon-edit />
</el-button>
<el-popconfirm :title="t('确认删除?')" placement="left" @confirm="del(row.id)">
<template #reference>
<el-button :key="row.id" :loading="delLoading && delId === row.id" type="danger">
<mel-icon-delete />
</el-button>
</template>
</el-popconfirm>
</template>
</vxe-column>
</me-vxe-table>
</el-card>
<add v-model="addOrUp" :data="info" @success="search(info ? params.page : 1)"></add>
</div>
</template>

<script setup lang="ts" name="Demo">
import { ListParams, Info, listApi, delApi } from '@/api/demo';
import { useLocalesI18n } from '@/locales/i18n';
import { bookType } from '@/dict/book';
import add from './components/add.vue';
let { t } = useLocalesI18n({}, [(locale: string) => import(`./lang/${locale}.json`), 'demo']);
const params = reactive(new ListParams());
const { loading, data, runAsync } = listApi();
const search = (page = params.page, size = params.size) => {
runAsync(Object.assign(params, { page, size }));
};
search(1);
const { runAsync: delRun, loading: delLoading } = delApi();
const delId = ref<number>();
const del = async (id: number) => {
delId.value = id;
await delRun(id);
search(1);
};
const addOrUp = ref(false);
const info = ref<Required<Info>>();
const showAddOrUp = (row?: Required<Info>) => {
info.value = row;
addOrUp.value = true;
};
</script>
<style lang="scss" scoped>
.demo {
.search-form {
::v-deep(.el-input) {
width: 215px;
}
}
}
</style>
8 changes: 8 additions & 0 deletions src/views/demo/lang/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"姓名": "Name",
"类型": "Type",
"书名": "Book Name",
"价格": "Price",
"章节": "Section",
"创建时间": "Create Time"
}

0 comments on commit 1707f46

Please sign in to comment.