前言

前一篇说了一堆服务端方面的实现,发现没讲界面上的东西,这次当一个小小的补充。

界面结构

我将编辑界面分为模版内容区、测试数据区、预览区三个部分,直接在界面中结合将测试数据插入到模版中得到整个文档的 DOM 结构,接着将文档整理放在一个 iframe 中展示。

结构划分

内容编辑器

这里采用了 ace 的方案,包括后面的测试数据板块也是一样的,所以这里只对前者做详解。

首先我们创建页面结构,这里省略了样式文件,利用 flex 等布局很容易实现。

<div>
<div>
模版内容
<pre id="template_editor" className="template" />
</div>
<div>
测试数据样例
<pre id="demo_data_editor" className="demo-data" />

预览
<iframe id='preview_iframe' className='preview' />
</div>
</div>

js方面因为后面的测试数据板块也会用到所以写一个通用的函数来初始化编辑器,这个编辑器的 api 也很容易使用,我们主要用到 getValuesetValue

// 一个生成编辑器的函数
import ace from 'ace-builds/src-min-noconflict/ace'
import EJSMode from 'ace-builds/src-min-noconflict/mode-ejs'
import JSONMode from 'ace-builds/src-min-noconflict/mode-json5'
import aceTheme from 'ace-builds/src-min-noconflict/theme-monokai'

function handleInitEditor (id, mode) {
// 根据元素id创建编辑器
const editor = ace.edit(id)
// 设置主题
editor.setTheme(aceTheme);
// 设置一些选项
editor.setOptions({
useSoftTabs: true,
navigateWithinSoftTabs: true
})
editor.session.setOptions({
tabSize: 2,
mode
})
return editor
}

const templateEditor = handleEditGenerater('template_editor', new EJSMode.Mode())

templateEditor.getValue() // 获取内容
templateEditor.setValue() // 设置内容

预览区

上面已经写好了 id='preview_iframe'iframe 作为预览区,那这里只需要搞定脚本即可。

import { parse } from 'json5'
import ejs from 'ejs'

const content = templateEditor.getValue()
const demoData = demoDataEditor.getValue()

const dataObj = parse(demoData);
const previewString = ejs.render(content, dataObj, { cache: false, debug: false })

const iframeDoc = document.getElementById('preview_iframe').contentDocument || document.getElementById('preview_iframe').contentWindow.document
iframeDoc.close()
iframeDoc.open()
iframeDoc.write(previewString)

这里有两个需要注意的地方:

  • 测试数据使用 json5 进行解析

    因为在实际使用是发现开发者可能会用写出不同格式的测试数据,如:

    {
    name: "lihua"
    }

    {
    name: 'lihua'
    }

    {
    "name": "lihua"
    }

    虽然只是小小的符号区别,但是实际发现对解析过程是有影响的,所以用 json5 这个包容性比较强的进行处理。

  • iframe 写入数据需要重置

    直接调用 write 方法只会追加数据,需要先关闭再打开。

其他

以上这部分完成之后关于编辑这一块大概的架子已经初具雏形了,剩下的边角料无非是在这个界面上再添加按钮调用之前写好的保存接口。

当然这里还缺少一个列表页用于搜索/查看所有的模版,这个比较简单,用表格一套就完事了。

模版列表