✨ 完成大作业部分及其打磨
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
<script setup lang="ts">
|
||||
import BackButton from '~/components/BackButton.vue';
|
||||
import { MdEditor } from 'md-editor-v3';
|
||||
import 'md-editor-v3/lib/style.css';
|
||||
|
||||
const emit = defineEmits(['articleEditFinish']);
|
||||
const { baseContent, baseTitle, saveButton } = defineProps({
|
||||
baseContent: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
baseTitle: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
saveButton: {
|
||||
type: String,
|
||||
default: '保存文章',
|
||||
},
|
||||
});
|
||||
const content = ref(baseContent);
|
||||
const title = ref(baseTitle);
|
||||
|
||||
async function saveArticle() {
|
||||
if (title.value === '' || content.value === '') {
|
||||
await MessagePlugin.error('标题和正文不能为空');
|
||||
return;
|
||||
}
|
||||
emit('articleEditFinish', {
|
||||
title: title.value,
|
||||
content: content.value,
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="p-6">
|
||||
<back-button class="ml-3" />
|
||||
<div
|
||||
class="m-2 bg-white rounded-xl p-6 border-gray-200 border-2 min-h-[300px] dark:bg-neutral-800 dark:border-zinc-600"
|
||||
>
|
||||
<t-form @submit="saveArticle">
|
||||
<t-form-item name="title" label="标题">
|
||||
<t-input v-model="title"></t-input>
|
||||
</t-form-item>
|
||||
<t-form-item name="content" label="正文">
|
||||
<MdEditor v-model="content" :theme="useColorMode().preference"/>
|
||||
</t-form-item>
|
||||
<t-form-item>
|
||||
<t-button theme="primary" type="submit">{{ saveButton }}</t-button>
|
||||
</t-form-item>
|
||||
</t-form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<t-button theme="primary" variant="base" @click="() => useRouter().back()">
|
||||
<t-icon name="arrow-left" size="22px" />返回
|
||||
</t-button>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,116 @@
|
||||
<script setup lang="tsx">
|
||||
import { ExampleUserInfo } from '~/stores/user';
|
||||
|
||||
const { avatarUrl, showWelcome, data } = defineProps({
|
||||
avatarUrl: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
showWelcome: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
data: {
|
||||
type: ExampleUserInfo,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
|
||||
function doShow(x: string) {
|
||||
const notShow = [
|
||||
'userAvatarPath',
|
||||
'userAvatarUrl',
|
||||
'userId',
|
||||
'usernameOrEmail',
|
||||
'lastGetTime',
|
||||
];
|
||||
for (const i of notShow) {
|
||||
if (x === i) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function toChinese(x: string) {
|
||||
const map = {
|
||||
userName: '用户名',
|
||||
userId: '用户ID',
|
||||
userEmail: '邮箱',
|
||||
phone: '手机号',
|
||||
lastGetTime: '最后登录时间',
|
||||
userAvatar: '头像',
|
||||
userAmount: '余额',
|
||||
userBirthday: '生日',
|
||||
};
|
||||
return map[x as keyof typeof map];
|
||||
}
|
||||
function getIcon(key: string) {
|
||||
const map = {
|
||||
userName: 'user',
|
||||
userEmail: 'mail',
|
||||
userAmount: 'money',
|
||||
userBirthday: 'cake',
|
||||
};
|
||||
const val = map[key as keyof typeof map];
|
||||
return <t-icon v-if="" class="t-menu__operations-icon" name={val} />;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="p-6">
|
||||
<div class="m-2">
|
||||
<slot name="header"></slot>
|
||||
</div>
|
||||
<div class="flex md:flex-row flex-col">
|
||||
<div
|
||||
class="flex-[1] m-2 h-full bg-white rounded-xl border-gray-200 border-2 min-h-[300px] min-w-48 dark:bg-zinc-800 dark:border-zinc-600"
|
||||
>
|
||||
<div class="flex flex-row md:flex-col justify-center p-4">
|
||||
<t-image
|
||||
:src="avatarUrl"
|
||||
alt="头像"
|
||||
:fit="'contain'"
|
||||
shape="circle"
|
||||
class="max-h-72 max-w-72 m-auto"
|
||||
/>
|
||||
<span
|
||||
v-if="showWelcome"
|
||||
class="text-2xl ml-auto mr-auto md:mt-6 mt-20 mb-6"
|
||||
>欢迎 {{ data.userName }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex-[2] m-2 bg-white rounded-xl border-gray-200 border-2 flex justify-center pt-8 min-w-[558px] dark:bg-[rgb(36,36,36)] dark:border-zinc-600"
|
||||
>
|
||||
<t-card
|
||||
title="个人信息"
|
||||
class="w-10/12 max-w-[700px]"
|
||||
:bordered="false"
|
||||
>
|
||||
<t-row v-for="(value, key) of data" :key="key" class="w-full">
|
||||
<div
|
||||
v-if="doShow(key)"
|
||||
class="border-collapse flex flex-row w-full h-10"
|
||||
>
|
||||
<t-col
|
||||
class="flex-[1] flex justify-center border-2 items-center dark:border-zinc-600"
|
||||
>{{ toChinese(key) }}</t-col
|
||||
>
|
||||
<t-col
|
||||
class="flex-[2] border-2 flex items-center dark:border-zinc-600"
|
||||
>
|
||||
<span class="ml-4">
|
||||
<component :is="getIcon(key)" />
|
||||
{{ value }}
|
||||
</span>
|
||||
</t-col>
|
||||
</div>
|
||||
</t-row>
|
||||
</t-card>
|
||||
</div>
|
||||
</div>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less"></style>
|
||||
@@ -13,16 +13,11 @@
|
||||
const pagination = defineModel<TableProps['pagination']>('pagination');
|
||||
|
||||
async function onPageChange(pageInfo: { current: number; pageSize: number }) {
|
||||
console.log('Page change');
|
||||
console.log(pageInfo);
|
||||
emit('pageChange', pageInfo);
|
||||
}
|
||||
function onRowClick(x: RowEventContext<TableRowData>) {
|
||||
emit('onRowClick', x);
|
||||
}
|
||||
function onSelectChange() {
|
||||
console.log('Select change');
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -37,7 +32,6 @@
|
||||
:lazy-load="true"
|
||||
:loading="loading"
|
||||
@page-change="onPageChange"
|
||||
@select-change="onSelectChange"
|
||||
@row-click="onRowClick"
|
||||
>
|
||||
</t-table>
|
||||
|
||||
Reference in New Issue
Block a user