富文本编辑器

官方文档:https://wangeditor-next.github.io/docs/

TextEditor.vue

html 复制代码
<template>
  <div style="border: 1px solid #ccc;">
    <Toolbar style="border-bottom: 1px solid #ccc" :editor="editor" :defaultConfig="toolbarConfig" :mode="mode" />
    <Editor style="height: 500px; overflow-y: hidden;" v-model="html" :defaultConfig="editorConfig" :mode="mode"
      @onCreated="onCreated" @onChange="handleChange" />
  </div>
</template>
<script>
import Vue from 'vue'
// import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { Editor, Toolbar } from '@wangeditor-next/editor-for-vue2'
import { importDeviceTroubleOrder, uploadVideo } from '@/api/index.js'

export default Vue.extend({
  props: {
    text: {
      type: String,
      default: ''
    }
  },
  components: { Editor, Toolbar },
  watch: {
    text() {
      // console.log('text', this.text)
      this.html = this.text
    }
  },
  data() {
    return {
      editor: null,
      html: '',
      // 工具栏配置
      toolbarConfig: {
        // 排除不需要的工具栏功能
        excludeKeys: [
          'fullScreen',   // 全屏
          // 'uploadVideo',  // 上传视频
          // 'group-video',  // 视频组
          // 'insertVideo',  // 插入视频
          // 'insertImage',  // 插入图片
          // 'uploadImage',  // 上传图片
          // 'codeBlock',    // 代码块
          // 'emotion'       // 表情
        ]
      },
      editorConfig: {
        placeholder: '请输入内容...',
        autoFocus: false,
        MENU_CONF: {
          uploadImage: {
            // fieldName: 'your-fileName',
            // maxFileSize: 10 * 1024 * 1024,  // 单个文件的最大体积限制,默认为 2M
            // maxNumberOfFiles: 1, // 限制一次最多上传 1 张图片
            // base64LimitSize: 10 * 1024 * 1024, // 10M 以下插入 base64
          }
        }
      },
      mode: 'default', // or 'simple'
    }
  },
  created() {
    this.html = this.text
    // 自定义图片上传
    this.editorConfig.MENU_CONF['uploadImage'] = {
      // server: '/tpdsa-web/hcspic/uploadImage',
      fieldName: 'file',
      maxFileSize: 10 * 1024 * 1024,  // 单个文件的最大体积限制,默认为 2M
      maxNumberOfFiles: 1, // 限制一次最多上传 1 张图片
      // base64LimitSize: 10 * 1024 * 1024, // 10M 以下插入 base64

      // 自定义上传
      async customUpload(file, insertFn) {
        // file 即选中的文件
        // 自己实现上传,并得到图片 url alt href
        // 最后插入图片
        console.log('file', file)
        const formData = new FormData()
        formData.append('file', file)
        importDeviceTroubleOrder(formData).then(res => {
          console.log(res)
          insertFn(res.data)
        })
      },
    }

    // 自定义视频上传
    this.editorConfig.MENU_CONF['uploadVideo'] = {
      // server: '/api/upload',
      // 最多可上传几个文件,默认为 5
      maxNumberOfFiles: 1,
      // 自定义增加 http  header
      headers: {
        Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
        // otherKey: 'xxx'
      },
      // 跨域是否传递 cookie ,默认为 false
      withCredentials: true,
      async customUpload(file, insertFn) {
        // file 即选中的文件
        // 自己实现上传,并得到视频 url poster
        // 最后插入视频
        const formData = new FormData()
        formData.append('file', file)
        uploadVideo(formData).then(res => {
          console.log(res)
          // 确保URL格式正确,避免编码问题
          const videoUrl = res.data.writeVideoUrl
          insertFn(videoUrl)
        })
      }
    }
  },

  mounted() {
  },
  beforeDestroy() {
    const editor = this.editor
    if (editor == null) return
    editor.destroy() // 组件销毁时,及时销毁编辑器
  },

  methods: {
    onCreated(editor) {
      this.editor = Object.seal(editor) // 一定要用 Object.seal() ,否则会报错
      // console.log(this.editor.getMenuConfig('uploadImage'))
      // console.log(this.editor.getMenuConfig('uploadVideo'))
    },

    handleChange(editor) {
      // console.log('change:', editor.children, editor.getHtml())
      this.$emit('input', editor.getHtml())
    }
  },
})
</script>
<!-- <style src="@wangeditor/editor/dist/css/style.css"></style> -->
<style src="@wangeditor-next/editor/dist/css/style.css"></style>
<style lang="scss" scoped>
::v-deep .w-e-bar-item button {
  font-size: 14px !important;
}

::v-deep {
  .color-block:after {
    background-image: none !important;
  }
}
</style>

demo

html 复制代码
<TextEditor :text="baseForm.eventDetail" @input="handleEventDetailChange" />

function handleEventDetailChange(val) {
  console.log(val, 'handleEventDetailChange')
  baseForm.value.eventDetail = val
}
相关推荐
miss2 分钟前
AI Agent 前端开发:一个初级工程师的踩坑成长之路
前端
清水寺小和尚2 分钟前
如何用400行代码构建OpenClaw
前端
锦木烁光3 分钟前
Flowable 实战:从架构解耦到多状态动态查询的高性能重构方案
前端·后端
子淼8124 分钟前
HTML入门指南:构建网页的基石
前端·html
农夫山泉不太甜6 分钟前
Electron离屏渲染技术详
前端
深念Y7 分钟前
Chrome MCP Server 配置失败全记录:一场历时数小时的“fetch failed”排查之旅
前端·自动化测试·chrome·http·ai·agent·mcp
一个有故事的男同学9 分钟前
从零打造专业级前端 SDK (四):错误监控与生产发布
前端
2601_9486061810 分钟前
从 jQuery → V/R → Lit:前端架构的 15 年轮回
前端·架构·jquery
wuhen_n15 分钟前
Vite 核心原理:ESM 带来的开发时“瞬移”体验
前端·javascript·vue.js
nibabaoo16 分钟前
前端开发攻略---vue3长列表性能优化终极指南:虚拟滚动、分页加载、时间分片等6种方案详解与代码实现
前端·javascript·vue.js·虚拟滚动·分页加载·长列表·时间分片