zoukankan      html  css  js  c++  java
  • Vue组件开发 -- Markdown

    利用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(/
    /g, '
    ' + 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

  • 相关阅读:
    【LuoguP4770】[NOI2018] 你的名字
    【LuoguP5171】Earthquake
    【LuoguP3747】[六省联考2017] 相逢是问候
    【LuoguP4916】魔力环
    YOLO2:实时目标检测视频教程,视频演示, Android Demo ,开源教学项目,论文。
    谷歌发布 TensorFlow Lite [官方网站,文档]
    Chinese-Text-Classification,用卷积神经网络基于 Tensorflow 实现的中文文本分类。
    Chinese-Text-Classification:Tensorflow CNN 模型实现的中文文本分类器[不分词版]
    Hinton's paper Dynamic Routing Between Capsules 的 Tensorflow , Keras ,Pytorch实现
    谷歌开发者:看可口可乐公司是怎么玩转TensorFlow的?
  • 原文地址:https://www.cnblogs.com/lalalagq/p/9959488.html
Copyright © 2011-2022 走看看