利用marked 和 highlight.js开发markdown组件

实现效果图如下:

markdown组件已这种形式<Markdown v-model="markdown"></Markdown>来绑定markdown的值
我们可以通过 value prop 和 input事件来达到这个效果用法详情

代码部分:


&lt;Markdown v-model="markdown"&gt;&lt;/Markdown&gt;

markdown组件

1.响应v-model


// 通过监听input事件 触发handleModelInput方法
&lt;textarea v-model="val" @input="handleModelInput" ref="text" @keydown.tab="tabMarkdown"&gt;&lt;/textarea&gt; import marked from 'marked'
import highlightJs from 'highlight.js'
export default {
props: ['value'],
data() {
return {
val: this.value
}
},
methods: {
handleModelInput() {// 通过$emit来把值返回给父组件
this.$emit('input', this.val)
}
}
}

2.插入markdown语法


async insertImg(e) { // 插入图片
let formData = new FormData(),
img = '';
formData.append('img', e.target.files[0]);
try {
let data = await this.axios({
method: 'post',
url: 'http://localhost:3000/markdown_upload_img',
data: formData
})
img = data.data.img
} catch (e) {
console.log(e)
} let val = `![图片描述](${img})`
this.setCursorPosition(this.$refs.text, val, 6)
},
insertLink () { //插入链接
this.maskBol = false
let val = `[链接描述](${this.link})`
this.setCursorPosition(this.$refs.text, val, 5)
},
setCursorPosition (dom,val,posLen) { // 设置光标位置
var cursorPosition = 0;
if(dom.selectionStart){
cursorPosition = dom.selectionStart;
}
this.insertAtCursor(dom,val);
dom.focus();
dom.setSelectionRange(dom.value.length,cursorPosition + (posLen || val.length));
this.val = dom.value
},
insertAtCursor(dom, val) { // 光标所在位置插入字符
if (document.selection){
dom.focus();
sel = document.selection.createRange();
sel.text = val;
sel.select();
}else if (dom.selectionStart || dom.selectionStart == '0'){
let startPos = dom.selectionStart;
let endPos = dom.selectionEnd;
let restoreTop = dom.scrollTop;
dom.value = dom.value.substring(0, startPos) + val + dom.value.substring(endPos, dom.value.length);
if (restoreTop &gt; 0){
dom.scrollTop = restoreTop;
}
dom.focus();
dom.selectionStart = startPos + val.length;
dom.selectionEnd = startPos + val.length;
} else {
dom.value += val;
dom.focus();
}
}

通过 setCursorPositioninsertAtCursor方法 插入光标所在位置并设置光标位置

  1. 转化markdown语法显示区域

&lt;div class="render fmt" v-html="renderHtml"&gt;&lt;/div&gt; // 实时转化textarea里面的markdown语法
computed: {
renderHtml() {
marked.setOptions({
renderer: new marked.Renderer(),
gfm: true, //允许 Git Hub标准的markdown.
tables: true, //允许支持表格语法。该选项要求 gfm 为true。
breaks: true, //允许回车换行。该选项要求 gfm 为true。
pedantic: false, //尽可能地兼容 markdown.pl的晦涩部分。不纠正原始模型任何的不良行为和错误。
sanitize: true, //对输出进行过滤(清理),将忽略任何已经输入的html代码(标签)
smartLists: true, //使用比原生markdown更时髦的列表。 旧的列表将可能被作为pedantic的处理内容过滤掉.
smartypants: false, //使用更为时髦的标点,比如在引用语法中加入破折号。
highlight: function (code) {
return highlightJs.highlightAuto(code).value;
}
});
return marked(this.val)
}
}

因为习惯使用tab缩进,所以在textarea里面输入的时候 按tab会切换元素,不会进行缩进, 所有我们得处理下tab键


tabMarkdown (e) { // 禁止tabs键的默认事件,并设置tab等于4个空格
e.preventDefault()
let indent = ' '
let start = this.textarea.selectionStart
let end = this.textarea.selectionEnd
let selected = window.getSelection().toString()
selected = indent + selected.replace(/\n/g, '\n' + indent)
this.textarea.value = this.textarea.value.substring(0, start) + selected
+ this.textarea.value.substring(end);
this.textarea.setSelectionRange(start + indent.length, start
+ selected.length)
}

markdown样式我是直接从 segmentfault上抠下来的

完整代码,点此获取

博客地址

原文地址:https://segmentfault.com/a/1190000012866925

Vue组件开发 -- Markdown的更多相关文章

  1. vue前端开发那些事——vue组件开发

    vue的学习曲线不是很陡(相比其它框架,如anglarjs),官方文档比较全面,分为基础篇和高级篇.我们刚开始学习的时候,肯定像引用jquery那样,先把vue的js引进来,然后学习基础内容.如果仅仅 ...

  2. Vue组件开发实例(详细注释)

    Vue组件开发实例: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> &l ...

  3. Vue (三) --- Vue 组件开发

    ------------------------------------------------------------------好心情,会让你峰回路转. 5. 组件化开发 5.1 组件[compo ...

  4. vue 组件开发、vue自动化工具、axios使用与router的使用(3)

    一. 组件化开发 1.1 组件[component] 在网页中实现一个功能,需要使用html定义功能的内容结构,使用css声明功能的外观样式,还要使用js定义功能的特效,因此就产生了一个功能先关的代码 ...

  5. 三: vue组件开发及自动化工具vue-cli

    一: 组件化开发 1 组件 1: 组件(Component)是自定义封装的功能.在前端开发过程中,经常出现多个网页的功能是重复的,而且很多不同的网站之间,也存在同样的功能. 2: 什么是组件 而在网页 ...

  6. vue 开发系列(三) vue 组件开发

    概要 vue 的一个特点是进行组件开发,组件的优势是我们可以封装自己的控件,实现重用,比如我们在平台中封装了自己的附件控件,输入控件等. 组件的开发 在vue 中一个组件,就是一个独立的.vue 文件 ...

  7. Vue组件开发实践之scopedSlot的传递

    收录待用,修改转载已取得腾讯云授权 导语 现今的前端开发都讲究模块化组件化,即把公共的交互和功能封装到一个个的组件之中,在开发整体界面的时候就能像搭积木一样快速清晰高效.在使用Vue开发我们的vhtm ...

  8. Vue组件开发分享

    在开始本文之前,你可能需要先了解以下相关内容: Vue.js  一款高性能轻量化的MVVM框架 Webpack  前端模块化代码构建工具 Vue组件介绍 基于vue.js高效的双向数据绑定特性,让我们 ...

  9. vue组件开发练习--焦点图切换

    1.前言 vue用了有一段时间了,开发的后台管理系统也趋于完善,现在时间比较算是有点空闲吧!这个空闲时间我在研究vue的另外的一些玩法,比如组件,插件等.今天,我就分享一个组件的练手项目--焦点图切换 ...

随机推荐

  1. js 时间戳 中国标准时间 年月日 日期之间的转换

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. anshi

    env.js主要是帮助我们读取根目录下以.env开头的环境变量,并判断是否生效. 比如在根目录下创建一个.env.local文件 改写一个环境变量 而没有改之前,它是在3000端口打开 path.js ...

  3. CF487E Tourists(圆方树+堆+链剖)

    本题解并不提供圆方树讲解. 所以不会圆方树的出门右转问yyb 没有修改的话圆方树+链剖. 方点的权值为点双连通分量里的最小值. 然后修改的话圆点照修,每一个方点维护一个小根堆. 考虑到可能被菊花卡死. ...

  4. WordCount合作--自己部分

    前言: (1)合作者:201631062127,201631062625 (2)合作代码地址:WordCount 一.结对的PSP表格: PSP2.1 PSP阶段 预估耗时 (分钟) 实际耗时 (分钟 ...

  5. markdown图片设置

    工具:typora 1. 设置图片大小(本节引用自 https://support.typora.io/Resize-Image/) Typora允许使用<img>标签显示图像,也可用于调 ...

  6. 【Codeforces Round #483 (Div. 2) C】Finite or not?

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 有个性质. 如果p/q是分数的最简形式. 那么p/q能化成有限小数. 当且仅当q的质因数分解形式中只有质因子2和5 (且不能出现其他 ...

  7. 【转】C# winform 加载网页 模拟键盘输入自动接入访问网络

    [转]C# winform 加载网页 模拟键盘输入自动接入访问网络 声明: 本文原创,首发于博客园 http://www.cnblogs.com/EasyInvoice/p/6070563.html  ...

  8. 王立平-bmp.compress()

    bmp.compress(Bitmap.CompressFormat.JPEG, 30, baos); //30 是压缩率,表示压缩70%; 假设不压缩是100,表示压缩率为0

  9. Android实战简易教程-第十三枪(五大布局研究)

    我们知道Android系统应用程序通常是由多个Activity组成,而这些Activity以视图的形式展如今我们面前, 视图都是由一个一个的组件构成的. 组件就是我们常见的Button.TextEdi ...

  10. 确保 Xcode 每次 Build 时都自己主动更新资源

    參考:p=22" target="_blank">http://quick.cocoachina.com/?p=22 刚建立的quickproject.每次修改lu ...