近期我完成了古籍处理板块页面升级,补充完成原文、句读、翻译的清空、保存和编辑(其中句读仅可修改标点)功能,新增原文和句读的繁简体切换功能
一、古籍处理板块整体页面升级
将原来一整个页面呈现的布局改为分栏呈现,更加清晰美观
组件结构概览
本页面主要由三部分组成:
侧边栏(
<el-aside>
)顶部导航栏(<el-header>)
内容区域(
<el-main>
)折叠按钮(用于侧边栏展开/收起)
页面更新机制详解
侧边栏显示逻辑(v-if="showAside"
)
使用 Vue 的
<transition name="aside-slide">
实现侧边栏渐现/渐隐动画;el-aside
中使用多个catalog-item
模拟目录结构,子模块(如“翻译”)支持展开/收起。
<el-aside v-if="showAside" class="aside">
各菜单项的可点击状态通过 originalText?.trim()
等条件控制 disabled
类,防止未完成前置操作时点击。
折叠按钮逻辑(toggleAside)
使用
:class="showAside ? 'from-aside' : 'from-left'"
控制其在侧边栏关闭或展开时的定位;点击按钮调用
toggleAside
切换showAside
状态。<div class="sider-toggle-button" :class="showAside ? 'from-aside' : 'from-left'" @click="toggleAside">
按钮图标通过动态绑定
d
属性显示左/右箭头。
主内容更新逻辑(动态布局切换)
核心思想:通过 isSplitView
和 activeTab
状态控制内容展示区域。
场景一:仅展示原文(初始状态)
<div v-if="!isSplitView" class="content-panel center-panel">
场景二:分栏展示(切换功能后)
<template v-if="isSplitView">
<div class="content-panel left-panel"> <!-- 固定句读 -->
<div class="content-panel right-panel"> <!-- 动态呈现翻译、知识图谱等 -->
使用
<transition name="tab-flip" mode="out-in">
为右侧内容切换添加翻页动画;:key="activeTab"
确保 DOM 被销毁/重建,从而触发动画。
交互逻辑和状态控制
// 修改后的 handleClick 函数
function handleClick(tab) {
if (tab === '原文' && !isSplitView.value) {
activeTab.value = tab;
return; // 初始原文居中
}
if (tab === '句读处理') {
if (!originalText.value.trim()) {
alert('请先输入或上传原文内容!');
return;
}
activeTab.value = '原文'; // 右侧初始显示原文
isSplitView.value = true; // 启动分栏布局
if (segmentedText.value === '') {
saveContent();
}
return;
}
if (['白话版翻译', '大众版翻译', '学术版翻译'].includes(tab)) {
if (!originalText.value.trim() || !segmentedText.value.trim()) {
alert('请先完成原文输入和句读处理!');
return;
}
const version = tab.replace('翻译', '');
translationVersion.value = version;
activeTab.value = tab;
isSplitView.value = true;
if (translationResults.value[version]) {
translationResult.value = translationResults.value[version];
return;
}
showTranslation();
generateKnowledgeGraph();
return;
}
if (tab === '知识图谱') {
//点进知识图谱页面
if (!originalText.value.trim()) {
alert('请先输入或上传原文内容!');
return;
}
activeTab.value = tab;
isSplitView.value = true;
if (!translationResult.value?.trim()) {
alert('请先进行翻译操作!');
return;
}
generateKnowledgeGraph()
} else {
activeTab.value = tab;
// 其他未指定的标签页也使用分栏布局
isSplitView.value = true;
}
if (tab === '生成配图') {
if (!originalText.value.trim() || !segmentedText.value.trim()) {
alert('请先完成原文输入和句读处理!');
return;
}
activeTab.value = tab;
isSplitView.value = true;
if (graph.value === '') {
generateGraph();
}
return;
}
if (tab === '生成PPT') {
if (!originalText.value.trim()) {
alert('请先完成原文输入!');
return;
}
activeTab.value = tab;
router.push('/test');
return;
}
// 默认行为
activeTab.value = tab;
isSplitView.value = true;
}
样式亮点分析(CSS)
1. 温润复古风配色与字体
背景色使用米色、棕色渐变(#f9f4ec, #f3e9e4 等)
字体采用
Noto Serif SC
,凸显文雅古籍阅读氛围
2. 动画与过渡设计
aside-slide
控制侧边栏渐现/缩回宽度与透明度tab-flip
采用 3D 视角切换内容,增强“翻书”体验
.dynamic-content-container {
perspective: 1200px; /* 为翻转动画添加深度 */
}
3. 响应式布局控制
split-view
类名加上左右两栏固定宽度并设定gap
间距;使用
v-if
分块渲染,确保初始加载性能更好。
效果展示
二、古籍处理板块细节处理
补充完成原文、句读、翻译的清空、保存和编辑(其中句读仅可修改标点)功能
通过 handleClear()
分流调用对应清空函数:
const handleClear = () => {
if (clearSource.value === 'original') {
clearOriginalContent();
clearGraph(); // 清图形
clearAnnotation(); // 清标注
} else if (clearSource.value === 'segmented') {
clearSegmentedContent();
} else if (clearSource.value === 'translation') {
clearTranslationContent();
}
};
保存,自动比对
原文自动清空翻译和句读结果,句读则自动清空翻译内容
if (originalText.value.trim() !== savedOriginalText.value.trim()) {
segmentedText.value = '';
translationResult.value = '';
...
}
逻辑说明:
避免重复提交。
更新原文后,重置下游数据(句读 + 翻译)以防“脏数据”。句读类似
限制用户编辑句读内容时“只能修改标点”
watch(segmentedText, (newVal, oldVal) => {
if (!isEditingSegmented.value || ignoreNextSegmentedChange.value) return;
const chars = extractCharacters(newVal);
if (chars !== originalCharacters.value) {
segmentedText.value = lastValidSegmentedText;
showWarningDialog.value = true;
} else {
lastValidSegmentedText = newVal;
}
})
关键实现:
通过
extractCharacters()
提取文本中非标点字符。利用
watch
监听segmentedText
的变化:若用户插入或删除了非标点字符,即触发“还原 + 弹窗提示”。
优点:
提供 柔性保护机制,防止破坏句读处理结果的语义结构。
UI 体验更佳,及时告知用户限制范围。
新增原文和句读的繁简体切换功能
引入 opencc-js
模块
import * as OpenCC from 'opencc-js'
let s2t, t2s
onMounted(() => {
s2t = OpenCC.Converter({ from: 'cn', to: 'tw' })
t2s = OpenCC.Converter({ from: 'tw', to: 'cn' })
})
使用
opencc-js
实现中文简繁转换。初始化两个转换器:
s2t
:简体 ➝ 繁体t2s
:繁体 ➝ 简体
自动识别文本字符类型
const detectCharType = (text) => {
if (!text.trim()) return 'simplified'
const converted = OpenCC.Converter({ from: 'tw', to: 'cn' })(text)
return converted === text ? 'simplified' : 'traditional'
}
原理:若将文本“繁转简”后没有变化,说明原文是简体。
简洁有效,用于首次渲染自动识别字符类型。
原文简繁切换
const toggleOriginalCharType = () => {
if (!originalText.value.trim()) return
if (charType.value === 'simplified') {
originalText.value = s2t(originalText.value)
charType.value = 'traditional'
} else {
originalText.value = t2s(originalText.value)
charType.value = 'simplified'
}
}
支持双向切换。
charType
用于记录当前状态,避免冗余转换。
句读简繁切换 + watch 忽略机制
const toggleSegmentedCharType = () => {
if (!segmentedText.value.trim()) return
ignoreNextSegmentedChange.value = true // 临时跳过编辑监听器
if (segmentedCharType.value === 'simplified') {
segmentedText.value = s2t(segmentedText.value)
segmentedCharType.value = 'traditional'
} else {
segmentedText.value = t2s(segmentedText.value)
segmentedCharType.value = 'simplified'
}
setTimeout(() => {
ignoreNextSegmentedChange.value = false
}, 0)
}
背景说明:
之前的代码中添加了“只能修改标点”的限制(通过 watch(segmentedText)
实现),若转换简繁文字,会被误判为“修改了文字”。
解决方案:
设置标志
ignoreNextSegmentedChange = true
临时跳过监听器执行;利用
setTimeout(..., 0)
确保 DOM 更新后自动恢复监听逻辑。