vue3+wangEditor5/vue-quill自定义上传音频+视频

一.各种编辑器分析

Quill

这是另一个常用的富文本编辑器,它提供了许多可定制的功能和事件,并且也有一2个官方的 Vue 3 组件

wangEditor5

wangEditor5用在Vue3中自定义扩展音频、视频、图片菜单;并扩展音频元素节点,保证音频节点的插入、读取、回写功能正常;支持动态修改尺寸

二. vue-quill

官网地址

(一)安装

npm install @vueup/vue-quill@alpha --save

(二)使用

Editor/index.vue

<template>
  <div class="editor">
    <el-upload
      class="avatar-uploader-editor"
      action="#"
      :before-upload="beforeAvatarUpload"
      accept=".jpg, .png, .gif, .jpeg"
      :http-request="handleFileChange"
      :show-file-list="false"
    >
      <el-button type="default" style="display: none; font-size: 14px"
        ><el-icon><UploadFilled /></el-icon>上传图片</el-button
      >
    </el-upload>
    <quill-editor
      ref="editorRef"
      v-model:content="content"
      contentType="html"
      @textChange="e => $emit('update:modelValue', content)"
      @blur="changeQuillEditor"
      :options="options"
      :style="styles"
    />
  </div>
</template>

<script setup>
import { QuillEditor, Quill } from '@vueup/vue-quill'
import '@vueup/vue-quill/dist/vue-quill.snow.css'
const { proxy } = getCurrentInstance()
const props = defineProps({
  /* 编辑器的内容 */
  modelValue: {
    type: String
  },
  /* 高度 */
  height: {
    type: Number,
    default: null
  },
  /* 最小高度 */
  minHeight: {
    type: Number,
    default: null
  },
  /* 只读 */
  readOnly: {
    type: Boolean,
    default: false
  }
})

const options = ref({
  theme: 'snow',
  bounds: document.body,
  debug: 'warn',
  modules: {
    // 工具栏配置
    toolbar: {
      container: [
        ['bold', 'italic', 'underline', 'strike'], // 加粗 斜体 下划线 删除线
        ['blockquote', 'code-block'], // 引用  代码块
        [{ list: 'ordered' }, { list: 'bullet' }], // 有序、无序列表
        [{ indent: '-1' }, { indent: '+1' }], // 缩进
        [{ size: ['small', false, 'large', 'huge'] }], // 字体大小
        [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题
        [{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色
        [{ align: [] }], // 对齐方式
        ['clean'], // 清除文本格式
        ['image', 'video'] // 链接、图片、视频
      ],
      handlers: {
        image: function (value) {
          if (value) {
            if (props.readOnly) {
              return false
            }
            // 触发input框选择图片文件
            document.querySelector('.avatar-uploader-editor input').click()
          } else {
            Quill.format('image', false)
          }
        }
      }
    }
  },
  placeholder: props.readOnly ? '' : '请输入内容',
  readOnly: props.readOnly
  // theme: 'snow'
})
const styles = computed(() => {
  let style = {}
  if (props.minHeight) {
    style.minHeight = `${props.minHeight}px`
  }
  if (props.height) {
    style.height = `${props.height}px`
  }
  return style
})
/**** 上传图片 start */
const editorRef = ref(null)
/**文件上传 限制条件
 *
 * @param {*} rawFile
 */
function beforeAvatarUpload(rawFile) {
  if (rawFile.size / 1024 / 1024 > 5) {
    proxy.$modal.msgError('单个文件不能超过5MB!')
    return false
  }
  let quill = toRaw(editorRef.value).getQuill()
  // 把图片转成base64
  getBase64(rawFile, url => {
    let length = quill.selection.savedRange.index
    // 插入图片,res为服务器返回的图片链接地址
    quill.insertEmbed(length, 'image', url)
  })
}
//工具函数
const getBase64 = (img, callback) => {
  const reader = new FileReader()
  reader.addEventListener('load', () => callback(reader.result))
  reader.readAsDataURL(img)
}
// 
async function handleFileChange(params) {
  let formData = new FormData()
  formData.append('file', params.file)
}
/**** 上传图片 end */
const content = ref('')
watch(
  () => props.modelValue,
  v => {
    if (v !== content.value) {
      content.value = v === undefined ? '

'
: v } }, { immediate: true } ) /** 鼠标移开 */ const emit = defineEmits(['myClick']) const changeQuillEditor = () => { emit('myClick', content.value) } </script> <style> .editor, .ql-toolbar { white-space: pre-wrap !important; line-height: normal !important; } .quill-img { display: none; } .ql-snow .ql-tooltip[data-mode='link']::before { content: '请输入链接地址:'; } .ql-snow .ql-tooltip.ql-editing a.ql-action::after { border-right: 0px; content: '保存'; padding-right: 0px; } .ql-snow .ql-tooltip[data-mode='video']::before { content: '请输入视频地址:'; } .ql-snow .ql-picker.ql-size .ql-picker-label::before, .ql-snow .ql-picker.ql-size .ql-picker-item::before { content: '14px'; } .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='small']::before, .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='small']::before { content: '10px'; } .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='large']::before, .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='large']::before { content: '18px'; } .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='huge']::before, .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='huge']::before { content: '32px'; } .ql-snow .ql-picker.ql-header .ql-picker-label::before, .ql-snow .ql-picker.ql-header .ql-picker-item::before { content: '文本'; } .ql-snow .ql-picker.ql-header .ql-picker-label[data-value='1']::before, .ql-snow .ql-picker.ql-header .ql-picker-item[data-value='1']::before { content: '标题1'; } .ql-snow .ql-picker.ql-header .ql-picker-label[data-value='2']::before, .ql-snow .ql-picker.ql-header .ql-picker-item[data-value='2']::before { content: '标题2'; } .ql-snow .ql-picker.ql-header .ql-picker-label[data-value='3']::before, .ql-snow .ql-picker.ql-header .ql-picker-item[data-value='3']::before { content: '标题3'; } .ql-snow .ql-picker.ql-header .ql-picker-label[data-value='4']::before, .ql-snow .ql-picker.ql-header .ql-picker-item[data-value='4']::before { content: '标题4'; } .ql-snow .ql-picker.ql-header .ql-picker-label[data-value='5']::before, .ql-snow .ql-picker.ql-header .ql-picker-item[data-value='5']::before { content: '标题5'; } .ql-snow .ql-picker.ql-header .ql-picker-label[data-value='6']::before, .ql-snow .ql-picker.ql-header .ql-picker-item[data-value='6']::before { content: '标题6'; } .ql-snow .ql-picker.ql-font .ql-picker-label::before, .ql-snow .ql-picker.ql-font .ql-picker-item::before { content: '标准字体'; } .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='serif']::before, .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='serif']::before { content: '衬线字体'; } .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='monospace']::before, .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='monospace']::before { content: '等宽字体'; } </style>

vue3+wangEditor5/vue-quill自定义上传音频+视频_第1张图片

(三)功能注意点

  • 通过按钮上传图片,图片不能到指定位置
    解决:
 let quill = toRaw(editorRef.value).getQuill()
  let length = quill.selection.savedRange.index
    // 插入图片,res为服务器返回的图片链接地址
  quill.insertEmbed(length, 'image', url)
  • 清除编辑器的表单验证
<template>
  <div class="myEditor">
      <el-form
        ref="formRef"
        :model="formModel"
        :rules="rules"
        label-width="100px"
      >
        <editor
          v-model="formModel.detail"
          :min-height="192"
          @myClick="changeText"
          :readOnly="formModel.id ? true : false"
          class="w-100%"
        />
      </el-form>
  </div>
</template>

<script setup name="myEditor">
/** 清除编辑器的表单验证 */
const changeText = text => {
  if ((text && text == '

'
) || text == '


'
) { formModel.value.detail = null proxy.$refs['formRef'].validateField('detail') return false } if (formModel.value.detail) { proxy.$refs['formRef'].clearValidate('detail') // clearValidate()取消验证方法 } } </script>

(四)参考

  • vue3使用vueup/vue-quill富文本、并限制输入字数

三. wangeditor5

官网地址

(一) 安装

yarn add @wangeditor/editor
或者 npm install @wangeditor/editor --save
yarn add @wangeditor/editor-for-vue@next
或者 npm install @wangeditor/editor-for-vue@next --save

(二) 常见api

wangEditor 提供了丰富的 API ,可以进行任何编辑器操作。可参考文档

  const editor = editorRef.value
 - 插入内容文本:
   editor.insertText(' 222 ')
 - 插入节点:
 import { SlateTransforms } from '@wangeditor/editor'
  const node2 = [
      {
        type: 'video',
        src: 'https://www.runoob.com/try/demo_source/horse.mp3',
        children: [{ text: 'bbb' }]
      }
    ]
    SlateTransforms.insertNodes(editor, node2)
 - 获取所有已注册的菜单
   editor.getAllMenuKeys();
 - 获取html
 	editor.getHtml()
 - 获取所有配置参数
   editor.getConfig()
 - 获取鼠标以上所有配置
   editorRef.value.getConfig().hoverbarKeys

(三) 配置

1. 编辑器配置

支持 readOnly autoFocus maxLength 等配置,可参考文档。

// 编辑器配置
const editorConfig = {
     placeholder: '请输入内容...',
     readOnly: props.readonly,
     autoFocus: false,
     scroll: true,
    // 可继续其他配置...
    MENU_CONF: { /* 菜单配置 */ }
}

请注意,该文档中的所有回调函数,都不能以配置的形式传入,如 onCreated onChange onDestroyed 等。这些回调函数必须以 Vue 事件的方式传入

<Editor
    :editorId="editorId"
    :defaultConfig="editorConfig"
    :defaultContent="defaultContent"
    :defaultHtml="defaultHtml"
    style="height: 500px"
    
    
                    

你可能感兴趣的:(vue.js,vue-quill,wangEditor5,编辑器,富文本,vue3,富文本上传视频+音频)