第三篇. vue中使用vue-quill-editor富文本插件,圖片上傳,視頻上傳


1.安裝
vue-quill-editor github地址:https://github.com/surmon-china/vue-quill-editor
官方文檔地址:https://www.npmjs.com/package/vue-quill-editor
基於Quill、適用於Vue2的富文本編輯器,支持服務端渲染和單頁應用

npm install vue-quill-editor --save

安裝圖片拖動和變化大小的插件,需要在vue.config.js引入webpack中配置 不配置會出錯,具體鏈接(https://github.com/kensnyder/quill-image-resize-module/issues/54)
plugins: [
    new webpack.ProvidePlugin({
        'window.Quill': 'quill/dist/quill.js',
        'Quill': 'quill/dist/quill.js',
    }),
]
2.局部引入
import Vue from 'vue'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
import { quillEditor } from 'vue-quill-editor'
import Quill from 'quill'
import { ImageDrop } from 'quill-image-drop-module'  // 圖片拖動插件
import ImageResize from 'quill-image-resize-module'  // 圖片設置大小插件
Quill.register('modules/imageDrop', ImageDrop)       // 圖片拖動插件
Quill.register('modules/imageResize', ImageResize)   // 圖片設置大小插件
// 鼠標移入顯示title文字
import { addQuillTitle } from '@/assets/quill-title.js'
Vue.use(quillEditor)
// 圖片上傳接口
import { richTextImgUpload } from '@/api/uploadFIle'
3.工具欄配置
// 工具欄配置
const toolbarOptions = [
  ['bold', 'italic', 'underline', 'strike'], // 加粗,斜體,下划線,刪除線
  ['blockquote', 'code-block'], // 引用,代碼塊

  [{ header: 1 }, { header: 2 }], // 標題,鍵值對的形式;1、2表示字體大小
  [{ list: 'ordered' }, { list: 'bullet' }], // 列表
  [{ script: 'sub' }, { script: 'super' }], // 上下標
  [{ indent: '-1' }, { indent: '+1' }], // 縮進
  [{ direction: 'rtl' }], // 文本方向

  [{ size: ['small', false, 'large', 'huge'] }], // 字體大小
  [{ header: [1, 2, 3, 4, 5, 6, false] }], // 幾級標題

  [{ color: [] }, { background: [] }], // 字體顏色,字體背景顏色
  [{ font: [] }], // 字體
  [{ align: [] }], // 對齊方式

  ['clean'], // 清除字體樣式
  ['image', 'video'] // 上傳圖片、上傳視頻
]
/* 富文本編輯圖片上傳配置*/
const uploadConfig = {
  action: '', // 必填參數 圖片上傳地址
  methods: 'POST', // 必填參數 圖片上傳方式
  token: '', // 可選參數 如果需要token驗證,假設你的token有存放在sessionStorage
  name: 'img', // 必填參數 文件的參數名
  size: 500, // 可選參數   圖片大小,單位為Kb, 1M = 1024Kb
  accept: 'image/png, image/gif, image/jpeg, image/bmp, image/x-icon' // 可選 可上傳的圖片格式
}
4.data中初始化配置
data() {
    return {
      content: '',
      videoOrimg:true,
      editorOption: {
        placeholder: '請輸入...',
        modules: {
          imageResize: {}, //圖片拖動設置大小
          imageDrop: true, // 圖片拖動
          toolbar: {
            container: toolbarOptions, //工具欄
            handlers: {
              image: (value) => {
                if (value) {
                  // 這是是為了獲取你當前點擊的那個富文本框
                  this.videoOrimg = true
                  document.querySelectorAll('.upload-demo input')[0].click()
                } else {
                  this.quill.format('image', false)
                }
              },
              video: (value) => {
                if (value) {
                  // 這是是為了獲取你當前點擊的那個富文本框
                  this.videoOrimg = false
                  document.querySelectorAll('.upload-demo input')[0].click()
                } else {
                  this.quill.format('image', false)
                }
              }
            }
          }
        },
        theme: 'snow'
      }
    }
  },
5.模板中使用
<template>
  <div>
    <el-upload
      class="upload-demo"
      action="#"
      name="file"
      :http-request="requestUpload"
      :before-upload="beforeAvatarUpload"
      :on-success="handleSuccess"
      multiple
    />
    <quill-editor ref="toref" v-model="content" :options="editorOption"  />
  </div>
</template>
6.圖片上傳(視頻上傳同理)
因為是前后端分離的,富文本上傳圖片要單獨上傳,在content中替換為后端返回圖片地址。
 methods: {
    // 覆蓋默認的上傳行為
    requestUpload(params) {
      const formData = new FormData()
      formData.append('img', params.file)
       // 圖片
      if(this.videoOrimg){
        richTextImgUpload(formData).then((res) => {
          params.onSuccess(res)
        })
      }else{
        richTextVideoUpload(formData).then((res) => {
          params.onSuccess(res)
        })
      }
      
    },
    // 判斷圖片后綴
    beforeAvatarUpload(file) {
      console.log(file,'dasda')
      const isJPG = file.type === 'image/jpeg' || 'image/png'
      const isVideo = file.type === 'video/mp4'
      const isLt2M = file.size / 1024 / 1024 < 10
      // 圖片
      if(this.videoOrimg){
        if (!isJPG) {
          this.$message.error('上傳圖片只能是 JPG , PNG格式!')
        }
        if (!isLt2M) {
          this.$message.error('上傳圖片大小不能超過 10MB!')
        }
         return isJPG && isLt2M
      }else{
          if(!isVideo){
            this.$message.error('上傳視頻只能是 MP4格式!')
          }
          return isVideo
      }
     
    },
    // 上傳成功
    handleSuccess(res, file) {
      if (res.error == 0) {
        // 動態添加 ref  通過 eval () 去執行
        const toeval = this.$refs.toref.quill
        // eval() 函數可計算某個字符串,並執行其中的的 JavaScript 代碼。
        // 獲取光標所在位置
        const length = toeval.selection.savedRange.index
        // 插入圖片,res為服務器返回的圖片鏈接地址
         // 圖片
      if(this.videoOrimg){
        toeval.insertEmbed(
          length,
          'image',
          process.env.VUE_APP_BASE_API_ORIGIN + res.data.imgscr
        )
      }else{
        toeval.insertEmbed(
          length,
          'video',
          process.env.VUE_APP_BASE_API_ORIGIN + res.data.imgscr
        )
      }
        // 調整光標到最后
        toeval.setSelection(length + 1)
      }
    },
    // 將內容上傳給父組件
    postContent() {
      this.$emit('getContent', this.content)
    },
  },
7.quill-title.js內容
const titleConfig = {
    'ql-bold':'加粗',
    'ql-color':'顏色',
    'ql-font':'字體',
    'ql-code':'插入代碼',
    'ql-italic':'斜體',
    'ql-link':'添加鏈接',
    'ql-background':'背景顏色',
    'ql-size':'字體大小',
    'ql-strike':'刪除線',
    'ql-script':'上標/下標',
    'ql-underline':'下划線',
    'ql-blockquote':'引用',
    'ql-header':'標題',
    'ql-indent':'縮進',
    'ql-list':'列表',
    'ql-align':'文本對齊',
    'ql-direction':'文本方向',
    'ql-code-block':'代碼塊',
    'ql-formula':'公式',
    'ql-image':'圖片',
    'ql-video':'視頻',
    'ql-clean':'清除字體樣式'
  };
   
  export function addQuillTitle(){
    const oToolBar = document.querySelector('.ql-toolbar'),
          aButton = oToolBar.querySelectorAll('button'),
          aSelect =  oToolBar.querySelectorAll('select');
    aButton.forEach(function(item){
      if(item.className === 'ql-script'){
        item.value === 'sub' ? item.title = '下標': item.title = '上標';
      }else if(item.className === 'ql-indent'){
        item.value === '+1' ? item.title ='向右縮進': item.title ='向左縮進';
      }else{
        item.title = titleConfig[item.classList[0]];
      }
    });
    aSelect.forEach(function(item){
      item.parentNode.title = titleConfig[item.classList[0]];
    });
  }
8.完整代碼
<template>
  <div>
    <el-upload
      class="upload-demo"
      action="#"
      name="file"
      :http-request="requestUpload"
      :before-upload="beforeAvatarUpload"
      :on-success="handleSuccess"
      multiple
    />
    <quill-editor ref="toref" v-model="content" :options="editorOption"  />
  </div>
</template>

<script>
import Vue from 'vue'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
import { quillEditor } from 'vue-quill-editor'
import Quill from 'quill'
import { ImageDrop } from 'quill-image-drop-module'  // 圖片拖動插件
import ImageResize from 'quill-image-resize-module'  // 圖片設置大小插件
Quill.register('modules/imageDrop', ImageDrop)       // 圖片拖動插件
Quill.register('modules/imageResize', ImageResize)   // 圖片設置大小插件
// 鼠標移入顯示title文字
import { addQuillTitle } from '@/assets/quill-title.js'
Vue.use(quillEditor)
// 圖片上傳接口
import { richTextImgUpload, richTextVideoUpload } from '@/api/uploadFIle'
// 工具欄配置
const toolbarOptions = [
  ['bold', 'italic', 'underline', 'strike'], // 加粗,斜體,下划線,刪除線
  ['blockquote', 'code-block'], // 引用,代碼塊

  [{ header: 1 }, { header: 2 }], // 標題,鍵值對的形式;1、2表示字體大小
  [{ list: 'ordered' }, { list: 'bullet' }], // 列表
  [{ script: 'sub' }, { script: 'super' }], // 上下標
  [{ indent: '-1' }, { indent: '+1' }], // 縮進
  [{ direction: 'rtl' }], // 文本方向

  [{ size: ['small', false, 'large', 'huge'] }], // 字體大小
  [{ header: [1, 2, 3, 4, 5, 6, false] }], // 幾級標題

  [{ color: [] }, { background: [] }], // 字體顏色,字體背景顏色
  [{ font: [] }], // 字體
  [{ align: [] }], // 對齊方式

  ['clean'], // 清除字體樣式
  ['image', 'video'] // 上傳圖片、上傳視頻
]
/* 富文本編輯圖片上傳配置*/
const uploadConfig = {
  action: '', // 必填參數 圖片上傳地址
  methods: 'POST', // 必填參數 圖片上傳方式
  token: '', // 可選參數 如果需要token驗證,假設你的token有存放在sessionStorage
  name: 'img', // 必填參數 文件的參數名
  size: 500, // 可選參數   圖片大小,單位為Kb, 1M = 1024Kb
  accept: 'image/png, image/gif, image/jpeg, image/bmp, image/x-icon' // 可選 可上傳的圖片格式
}
export default {
  components: {
    quillEditor
  },
  props: {
    contents:String,
    default:''
  },
  data() {
    return {
      content: '',
      videoOrimg:true,
      editorOption: {
        placeholder: '請輸入...',
        modules: {
          imageResize: {}, //圖片拖動設置大小
          imageDrop: true, // 圖片拖動
          toolbar: {
            container: toolbarOptions, //工具欄
            handlers: {
              image: (value) => {
                if (value) {
                  // 這是是為了獲取你當前點擊的那個富文本框
                  this.videoOrimg = true
                  document.querySelectorAll('.upload-demo input')[0].click()
                } else {
                  this.quill.format('image', false)
                }
              },
              video: (value) => {
                if (value) {
                  // 這是是為了獲取你當前點擊的那個富文本框
                  this.videoOrimg = false
                  document.querySelectorAll('.upload-demo input')[0].click()
                } else {
                  this.quill.format('image', false)
                }
              }
            }
          }
        },
        theme: 'snow'
      }
    }
  },
  mounted() {
    addQuillTitle()
  },
  methods: {
    // 覆蓋默認的上傳行為
    requestUpload(params) {
      const formData = new FormData()
      formData.append('img', params.file)
       // 圖片
      if(this.videoOrimg){
        richTextImgUpload(formData).then((res) => {
          params.onSuccess(res)
        })
      }else{
        richTextVideoUpload(formData).then((res) => {
          params.onSuccess(res)
        })
      }
      
    },
    // 判斷圖片后綴
    beforeAvatarUpload(file) {
      console.log(file,'dasda')
      const isJPG = file.type === 'image/jpeg' || 'image/png'
      const isVideo = file.type === 'video/mp4'
      const isLt2M = file.size / 1024 / 1024 < 10
      // 圖片
      if(this.videoOrimg){
        if (!isJPG) {
          this.$message.error('上傳圖片只能是 JPG , PNG格式!')
        }
        if (!isLt2M) {
          this.$message.error('上傳圖片大小不能超過 10MB!')
        }
         return isJPG && isLt2M
      }else{
          if(!isVideo){
            this.$message.error('上傳視頻只能是 MP4格式!')
          }
          return isVideo
      }
    },
    // 上傳成功
    handleSuccess(res, file) {
      if (res.error == 0) {
        // 動態添加 ref  通過 eval () 去執行
        const toeval = this.$refs.toref.quill
        // eval() 函數可計算某個字符串,並執行其中的的 JavaScript 代碼。
        // 獲取光標所在位置
        const length = toeval.selection.savedRange.index
        // 插入圖片,res為服務器返回的圖片鏈接地址
         // 圖片
      if(this.videoOrimg){
        toeval.insertEmbed(
          length,
          'image',
          process.env.VUE_APP_BASE_API_ORIGIN + res.data.imgscr
        )
      }else{
        toeval.insertEmbed(
          length,
          'video',
          process.env.VUE_APP_BASE_API_ORIGIN + res.data.imgscr
        )
      }
        // 調整光標到最后
        toeval.setSelection(length + 1)
      }
    },
    // 將內容上傳給父組件
    postContent() {
      this.$emit('getContent', this.content)
    },
  },
  watch: {
    contents:{
        immediate: true,    // 這句重要
        handler (val) {
            this.content = this.contents
        }
    }
  }
}
</script>

<style scoped>
.upload-demo {
  display: none;
}
</style>

9.預覽


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM