vue-quill-editor(富文本) 在 vue 中如何使用

  1. 安裝 vue-quill-editor
    npm install vue-quill-editor -S
  2. 安裝quill
    npm install quill -S
  3. 引入
    import { quillEditor } from 'vue-quill-editor' // 調用富文本編輯器
    import 'quill/dist/quill.snow.css' // 富文本編輯器外部引用樣式 三種樣式三選一引入即可
    //import 'quill/dist/quill.core.css'
    //import 'quill/dist/quill.bubble.css'
    import * as Quill from 'quill'; // 富文本基於quill
  4. 使用

<!-- template部分 -->

<quill-editor
    v-model="content"
    ref="myQuillEditor"
    :options="editorOption"
    @focus="onEditorFocus($event)"
    @blur="onEditorBlur($event)"
    @change="onEditorChange($event)">
</quill-editor>

<!-- js data部分 -->

``

editor: null,   // 富文本編輯器對象
content: `<p></p><p><br></p><ol></ol>`, // 富文本編輯器默認內容
editorOption: { //  富文本編輯器配置
    modules: {
        toolbar: '#toolbar'
    },
    theme: 'snow',
    placeholder: '請輸入正文'
},

<!-- js mounted部分 -->

this.editor = this.$refs.myQuillEditor.quill;

<!-- js beforeDestroy部分 -->

this.editor = null;
delete this.editor;

<!-- js methods部分 -->

// 準備富文本編輯器
onEditorReady (editor) {},
// 富文本編輯器 失去焦點事件
onEditorBlur (editor) {},
// 富文本編輯器 獲得焦點事件
onEditorFocus (editor) {},
// 富文本編輯器 內容改變事件
onEditorChange (editor) {},

<!-- js components部分 -->

components: {
    quillEditor
}
  1. 如果想自定義工具欄:
<!-- template部分 -->
<div id="toolbar" slot="toolbar">
    <button class="ql-bold" title="加粗">Bold</button>
    <select class="ql-header" title="段落格式">
        <option selected>正文</option>
        <option value="2">標題1</option>
        <option value="3">標題2</option>
        <option value="4">標題3</option>
    </select>
    <button class="ql-list" value="ordered" title="有序列表"></button>
    <button class="ql-list" value="bullet" title="無序列表"></button>
    <select class="ql-color" value="color" title="字體顏色"></select>
    <span class="icon-pic custom-icon" title="圖片" @click="insertImgClick($event)"></span>  <!-- 插入圖片 -->
    <span class="icon-video custom-icon" title="視頻" @click="insertImgClick($event)"></span>  <!-- 插入視頻 -->
</div>
<input style="display: none;" type="file" id="insert_image" @change="fileInsert($event)">  <!-- 選擇圖片input -->
<input style="display: none;" type="file" id="insert_video" @change="fileInsert($event)">  <!-- 選擇視頻input -->

<!-- js methods部分 -->
// 富文本編輯器 點擊插入圖片或者視頻
insertImgClick (e) {
    if (e.target.className.indexOf('icon-pic') != -1) {
        document.getElementById('insert_image').click();
    } else if (e.target.className.indexOf('icon-video') != -1) {
        document.getElementById('insert_video').click();
    }
},
// 富文本編輯器 點擊插入圖片或者視頻上傳並預覽
fileInsert (e) {
    var oFile = e.target.files[0];
    if (typeof (oFile) === 'undefined') {
        return;
    }
    let sExtensionName = oFile.name.substring(oFile.name.lastIndexOf('.') + 1).toLowerCase();   // 文件擴展名
    let sfileType = ''; // 上傳文件類型
    if (e.target.id == 'insert_image') {
        sfileType = 'image'
        if (sExtensionName !== 'png' && sExtensionName !== 'jpg' && sExtensionName !== 'jpeg') {
            alert('不支持該類型圖片');
            return;
        }
    }
    if (e.target.id == 'insert_video') {
        sfileType = 'video';
        if (sExtensionName !== 'mp4' && sExtensionName !== 'avi' && sExtensionName !== 'mov') {
            alert('不支持該類型視頻');
            return;
        }
        let maxSize = 100*1024*1024;    // 100MB
        if (oFile.size > maxSize) {
            alert('上傳視頻大小不能超過100MB');
            return;
        }
    }
    var reader = new FileReader();
    reader.readAsDataURL(oFile);
    reader.onloadend = () => {
        let formData = new FormData(); // 通過formdata上傳
        formData.append('file', oFile);
        let sUrl = '';
        if (sfileType == 'image') {
            sUrl = 'Pic';
        }
        if (sfileType == 'video') {
            sUrl = 'Vie';
        }
        var url = this.api_config + '/dealerIndex/upload' + sUrl + '.htm';
        this.axios.post(url, formData, {
            headers: { 'Content-Type': 'multipart/form-data' }
        }).then((res) => {
            this.editor.insertEmbed(this.editor.selection.savedRange.index, sfileType, res.data.data);  // 這個方法用來手動插入dom到編輯器裏
            let isAndroid = this.$is_android(); // 判斷是ios還是android
            if (isAndroid) {
                $('video').removeAttr('controls');
                $('video').attr('x5-video-player-type', 'h5');
            }
            this.editor.setSelection(this.editor.selection.savedRange.index + 1);  // 這個方法可以獲取光標位置
        }).catch((response) => {
            console.log('失敗', response);
        })
    }
},
關於編輯器裏面的一些操作可以到quill官方查看,用法和配置項的的介紹很詳細,很好用
  1. 如果想更好地操作插入的video,可以把iframe改成h5的video,通過下面這段代碼:
import { Quill } from 'vue-quill-editor'

// 源碼中是import直接倒入,這裏要用Quill.import引入
const BlockEmbed = Quill.import('blots/block/embed')
const Link = Quill.import('formats/link')

const ATTRIBUTES = ['height', 'width']

class Video extends BlockEmbed {
  static create (value) {
    const node = super.create(value)
    // 添加video標籤所需的屬性
    node.setAttribute('controls', 'controls')   // 控制播放器
    node.setAttribute('type', 'video/mp4')
    node.setAttribute('style', 'object-fit:fill;width: 100%;')
    node.setAttribute('preload', 'auto')    // auto - 當頁面加載後載入整個視頻  meta - 當頁面加載後只載入元數據  none - 當頁面加載後不載入視頻
    node.setAttribute('webkit-playsinline', 'true') // 兼容ios 不全屏播放
    node.setAttribute('playsinline', 'true')
    node.setAttribute('x-webkit-airplay', 'allow')
    // node.setAttribute('x5-video-player-type', 'h5') // 啓用H5播放器,是wechat安卓版特性
    node.setAttribute('x5-video-orientation', 'portraint') // 豎屏播放 聲明瞭h5才能使用  播放器支付的方向,landscape橫屏,portraint豎屏,默認值爲豎屏
    node.setAttribute('x5-playsinline', 'true') // 兼容安卓 不全屏播放
    node.setAttribute('x5-video-player-fullscreen', 'true')    // 全屏設置,設置爲 true 是防止橫屏
    node.setAttribute('src', this.sanitize(value))
    return node
  }

  static formats (domNode) {
    return ATTRIBUTES.reduce((formats, attribute) => {
      if (domNode.hasAttribute(attribute)) {
        formats[attribute] = domNode.getAttribute(attribute)
      }
      return formats
    }, {})
  }

  static sanitize (url) {
    return Link.sanitize(url) // eslint-disable-line import/no-named-as-default-member
  }

  static value (domNode) {
    return domNode.getAttribute('src')
  }

  format (name, value) {
    if (ATTRIBUTES.indexOf(name) > -1) {
      if (value) {
        this.domNode.setAttribute(name, value)
      } else {
        this.domNode.removeAttribute(name)
      }
    } else {
      super.format(name, value)
    }
  }

  html () {
    const { video } = this.value()
    return `<a href="${video}">${video}</a>`
  }
}
Video.blotName = 'video' // 這裏不用改,樓主不用iframe,直接替換掉原來,如果需要也可以保留原來的,這裏用個新的blot
Video.className = 'ql-video'
Video.tagName = 'video' // 用video標籤替換iframe

export default Video
然後再把它引入到有編輯器的那個文件裏:

import Video from '../../plugins/video.js'; // 插入h5 video視頻
Quill.register(Video, true);  // 註冊video

就是這麼多了~~~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章