refactor editor
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
<template>
|
||||
<section class="demo-section">
|
||||
<div class="section-heading">
|
||||
<div>
|
||||
<p class="eyebrow">文章场景</p>
|
||||
<h2>文章编辑与预览</h2>
|
||||
<p>切换正文类型,验证统一的 Article 数据结构。</p>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<t-button
|
||||
v-for="item in contentTypeOptions"
|
||||
:key="item.value"
|
||||
size="small"
|
||||
:theme="articleValue.contentType === item.value ? 'primary' : 'default'"
|
||||
variant="outline"
|
||||
@click="selectContentType(item.value)"
|
||||
v-text="item.label"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="demo-grid">
|
||||
<article class="demo-card">
|
||||
<div class="card-heading">
|
||||
<h3>ArticleEditor</h3>
|
||||
<t-button size="small" theme="primary" @click="submitArticle">提交文章</t-button>
|
||||
</div>
|
||||
<t-input v-model="articleValue.title" class="title-input" placeholder="文章标题" />
|
||||
<article-editor
|
||||
ref="articleEditorRef"
|
||||
:model-value="articleValue"
|
||||
:upload-image="uploadDemoMedia"
|
||||
:upload-video="uploadDemoMedia"
|
||||
@change="onArticleChange"
|
||||
@update:model-value="onArticleChange"
|
||||
/>
|
||||
<p class="status" v-text="articleStatus" />
|
||||
</article>
|
||||
|
||||
<article class="demo-card">
|
||||
<div class="card-heading">
|
||||
<h3>ArticleView</h3>
|
||||
<span v-text="articleValue.contentType" />
|
||||
</div>
|
||||
<article-view :article="articleValue" />
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
ArticleEditor,
|
||||
ArticleView
|
||||
} from "timi-tdesign-mobile";
|
||||
import type { ArticleEditorExpose } from "timi-tdesign-mobile";
|
||||
import type { Article, ArticleContentType } from "timi-web/editor";
|
||||
import { DEMO_ARTICLE_CONTENT, cloneArticle, uploadDemoMedia } from "../demo-data";
|
||||
|
||||
const contentTypeOptions: Array<{ label: string; value: ArticleContentType }> = [
|
||||
{ label: "纯文本", value: "TEXT" },
|
||||
{ label: "Markdown", value: "MARKDOWN" },
|
||||
{ label: "Tiptap", value: "TIP_TAP" }
|
||||
];
|
||||
const articleValue = ref<Article>(cloneArticle());
|
||||
const articleEditorRef = ref<ArticleEditorExpose>();
|
||||
const articleStatus = ref("等待提交");
|
||||
|
||||
function selectContentType(contentType: ArticleContentType) {
|
||||
const content = contentType === "TEXT"
|
||||
? "这是一段纯文本示例。"
|
||||
: contentType === "MARKDOWN"
|
||||
? "## Markdown 示例\n\n这是一段 Markdown 正文。"
|
||||
: DEMO_ARTICLE_CONTENT;
|
||||
articleValue.value = {
|
||||
...articleValue.value,
|
||||
contentType,
|
||||
content
|
||||
};
|
||||
}
|
||||
|
||||
function onArticleChange(value: Article) {
|
||||
articleValue.value = value;
|
||||
}
|
||||
|
||||
async function submitArticle() {
|
||||
const value = await articleEditorRef.value?.submit();
|
||||
if (value) {
|
||||
articleValue.value = value;
|
||||
articleStatus.value = `已提交,${value.attachmentList?.length || 0} 个附件`;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.demo-section {
|
||||
.section-heading {
|
||||
align-items: flex-end;
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
h2 {
|
||||
margin: .25rem 0;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
color: var(--td-text-color-secondary);
|
||||
}
|
||||
}
|
||||
|
||||
.eyebrow {
|
||||
font-size: .75rem;
|
||||
letter-spacing: .08em;
|
||||
text-transform: uppercase;
|
||||
color: var(--td-brand-color);
|
||||
}
|
||||
|
||||
.actions,
|
||||
.card-heading {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: .5rem;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.demo-grid {
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.demo-card {
|
||||
padding: 1rem;
|
||||
border: 1px solid var(--td-component-border);
|
||||
border-radius: .75rem;
|
||||
background: var(--td-bg-color-container);
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
span,
|
||||
.status {
|
||||
font-size: .75rem;
|
||||
color: var(--td-text-color-secondary);
|
||||
}
|
||||
}
|
||||
|
||||
.title-input {
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.status {
|
||||
margin: 1rem 0 0;
|
||||
}
|
||||
|
||||
@media (max-width: 48rem) {
|
||||
.section-heading,
|
||||
.card-heading {
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.actions {
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.demo-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user