- 该系列下Vue非组件式开发,纯粹拿Vue的一些便利特性做了些交互渲染
- Springboot + JPA + Mysql
- 前端 SemanticUI 、Jquery
Markdown保存文本值为空
看代码
<div class="page-content" id="md-content" style="z-index: 5 !important;">
<label>
<textarea name="content" v-model="content" style="display: none"></textarea>
</label>
</div>
定义用于接受文本的变量: content: '', //使用v-model双向绑定这个Markdown文本内容
<a @click="add" class="ui button red mini"><i class="send icon"></i>发布</a>
add: function() {
var content = this.content;
var form = new FormData();
form.append("content",content); //内容
alert(form.get("content"));
}
输出为空
具体原因是应为content没有绑定到具体的渲染节点上,editormd渲染出来的文本框是动态的Dom节点
节点
我们要将将content 绑定到 editormd-markdown-textarea 这个节点上,但由于这是动态渲染出来的,所以我们曲线救国,采取Jquery方式:
//这里采取的
this.content = $(".editormd-markdown-textarea").val(); //获取这个节点上的值
var content_two = this.content;
var form = new FormData(); //后继需要上传图片,所以这里采取的这种方式
form.append("content",content_two);
alert(form.get("content"));
渲染出结果
我们继续查看数据库
关于Markdown文件前端渲染问题
由于数据库中存储的是Markdown文件。直接放在前台会有格式问题,这里有俩种处理方式
- 前端使用 markdown-it 渲染,我们从后台拿到数据之后,在前台进行处理
<script src="https://cdnjs.cloudflare.com/ajax/libs/markdown-it/10.0.0/markdown-it.js"></script>
var data1 = {
blog: '',
reviews:[],
user:'',
content_vert:''
};
getBlogDetail: function () {
let bid = getUrlParms("bid"); //获取地址栏传递的blog id
let url = "blogs/" + bid;
axios.get(url).then(function (response) {
var result = response.data;
vue.blog = result.data.blog;
vue.content_vert = vue.blog.content; //转换的博客内容
//渲染Markdown文件
var md = window.markdownit();
vue.$nextTick(function () {
document.querySelector('#content').innerHTML = md.render(this.content_vert);
});
});
},
渲染成功
- 后端处理,采用commentMark jar包,具体可到github上下载使用实例
<!-- Markdown HTML文本格式转换 以及它的拓展依赖-->
<dependency>
<groupId>com.atlassian.commonmark</groupId>
<artifactId>commonmark</artifactId>
<version>0.14.0</version>
</dependency>
<dependency>
<groupId>com.atlassian.commonmark</groupId>
<artifactId>commonmark-ext-heading-anchor</artifactId>
<version>0.14.0</version>
</dependency>
<dependency>
<groupId>com.atlassian.commonmark</groupId>
<artifactId>commonmark-ext-gfm-tables</artifactId>
<version>0.14.0</version>
</dependency>
public class MarkdownUtils {
/**
* markdown格式转换成HTML格式
*/
public static String markdownToHtml(String markdown) {
Parser parser = Parser.builder().build();
Node document = parser.parse(markdown);
HtmlRenderer renderer = HtmlRenderer.builder().build();
return renderer.render(document);
}
/**
* 增加扩展[标题锚点,表格生成]
* Markdown转换成HTML
*/
public static String markdownToHtmlExtensions(String markdown) {
//h标题生成id
Set<Extension> headingAnchorExtensions = Collections.singleton(HeadingAnchorExtension.create());
//转换table的HTML
List<Extension> tableExtension = Collections.singletonList(TablesExtension.create());
Parser parser = Parser.builder()
.extensions(tableExtension)
.build();
Node document = parser.parse(markdown);
HtmlRenderer renderer = HtmlRenderer.builder()
.extensions(headingAnchorExtensions)
.extensions(tableExtension)
.attributeProviderFactory(context -> new CustomAttributeProvider())
.build();
return renderer.render(document);
}
/**
* 处理标签的属性
*/
static class CustomAttributeProvider implements AttributeProvider {
@Override
public void setAttributes(Node node, String tagName, Map<String, String> attributes) {
//改变a标签的target属性为_blank
if (node instanceof Link) {
attributes.put("target", "_blank");
}
if (node instanceof TableBlock) {
attributes.put("class", "ui celled table");
}
}
}
}
接着就是后端的业务处理
image.png
这种方式,实测在vue下回渲染失败,解决办法是我们需要使用这样 vue.$nextTick 函数进行处理,让渲染在dom更新之后执行,不然会报 渲染null错误。
网友评论