vue-quill-editor 富文本框编辑器

简介: 版权声明:本文首发 http://asing1elife.com ,转载请注明出处。 https://blog.csdn.net/asing1elife/article/details/82820611 ...
版权声明:本文首发 http://asing1elife.com ,转载请注明出处。 https://blog.csdn.net/asing1elife/article/details/82820611

基于quilljs实现的支持vue的富文本框编辑器

更多精彩

官网

  1. vue-quill-editor
  2. Toolbar Module - Quill
  3. vue-quill-image-upload

图片支持上传服务器并调整大小

  1. package.json 中加入 "quill-image-extend-module": "^1.1.2" 依赖
  2. 在编辑器组件中引入以下代码
<template>
  <div class="in-editor-panel">
    <quill-editor ref="quillEditor" v-model="content" :options="editorOption" @change="onChange">
    </quill-editor>
  </div>
</template>

<script type="text/ecmascript-6">
  import 'quill/dist/quill.core.css'
  import 'quill/dist/quill.snow.css'
  import { quillEditor, Quill } from 'vue-quill-editor'
  import { ImageExtend, QuillWatch } from 'quill-image-extend-module'
  import { hasClass } from 'assets/scripts/dom/dom'

  Quill.register('modules/ImageExtend', ImageExtend)

  export default {
    props: {
      value: {
        type: String,
        default: ''
      },
      toolbarMode: {
        type: Number,
        default: 0
      },
      placeholder: {
        type: String,
        default: '请输入内容'
      },
      height: {
        type: Number,
        default: 170
      },
      imagePath: {
        type: String,
        default: ''
      }
    },
    data () {
      return {
        content: '',
        toolbars: [
          [
            ['bold', 'italic', 'underline', 'strike'],
            ['blockquote', 'code-block'],
            [{'header': 1}, {'header': 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]}],
            [{'font': []}],
            [{'color': []}, {'background': []}],
            [{'align': []}],
            ['clean'],
            ['link', 'image', 'video']
          ],
          [
            ['bold', 'italic', 'underline'],
            ['blockquote', 'code-block'],
            [{'list': 'ordered'}, {'list': 'bullet'}],
            [{'header': [1, 2, 3, 4, 5, 6, false]}],
            [{'color': []}, {'background': []}],
            [{'align': []}],
            ['link', 'image', 'video']
          ],
          [
            ['bold', 'italic', 'underline'],
            ['blockquote', 'code-block'],
            [{'list': 'ordered'}, {'list': 'bullet'}],
            [{'color': []}, {'background': []}],
            ['insert']
          ]
        ],
        editorOption: {
          modules: {
            ImageExtend: {
              loading: true,
              name: 'image',
              size: 2,
              action: `/api/file/upload/image?filePath=${JSON.stringify(this.imagePath)}`,
              response: (res) => {
                return res.data
              }
            },
            toolbar: {
              container: [],
              handlers: {
                'image': function () {
                  QuillWatch.emit(this.quill.id)
                }
              }
            }
          },
          placeholder: this.placeholder
        }
      }
    },
    computed: {
      editor () {
        return this.$refs.quillEditor.quill
      }
    },
    watch: {
      // 监听父组件传入的内容
      value (newVal) {
        this.$nextTick(() => {
          this._listenerImage()
        })

        if (newVal === this.content) {
          return false
        }

        // 传入的内容不等于编辑器自身内容,则更新
        this.content = newVal
      },
      'content' () {
        this._listenerImage()
      }
    },
    created () {
      // 指定工具栏
      this.editorOption.modules.toolbar.container = this.toolbars[this.toolbarMode]
    },
    mounted () {
      // 设置编辑器高度
      this.editor.container.style.height = `${this.height}px`
    },
    methods: {
      // 显示宽度修改框
      _showWidthBox (event) {
        // 获取当前图片对象
        let currentImg = event.target

        // 弹出宽度输入框
        this.$prompt('请输入宽度', '提示', {
          inputValue: currentImg.width,
          confirmButtonText: '确定',
          cancelButtonText: '取消'
        }).then(({value}) => {
          // 赋值新宽度
          currentImg.width = value
        }).catch(() => {})
      },
      // 监听图片点击
      _listenerImage () {
        // 获取DOM对象
        let editor = document.getElementsByClassName('ql-editor')[0]
        let img = editor.getElementsByTagName('img')

        // 非空验证
        if (img.length === 0) {
          return
        }

        for (let i = 0; i < img.length; i++) {
          let currentImg = img[i]

          // 绑定且防止重复绑定
          currentImg.removeEventListener('dblclick', this._showWidthBox, false)
          currentImg.addEventListener('dblclick', this._showWidthBox, false)
        }
      },
      onChange () {
        // 告知父组件内容发生变化
        this.$emit('input', this.content)
      }
    },
    components: {
      quillEditor
    }
  }
</script>
目录
相关文章
|
1天前
|
设计模式 JavaScript 前端开发
Vue源码学习需要哪些工具和技能
【4月更文挑战第20天】学习Vue源码需具备的工具与技能:VS Code或WebStorm作为代码编辑器,Node.js与npm管理依赖,Git操作仓库。基础包括JavaScript、ES6+语法、前端知识(HTML/CSS/浏览器原理)及Vue基础知识。进阶则需源码阅读理解能力,调试技巧,熟悉设计模式和架构思想。学习方法强调系统学习、实践与持续关注Vue最新动态。
17 8
|
1天前
|
JavaScript 前端开发 编译器
Vue 源码学习路线
【4月更文挑战第20天】探索Vue源码涉及响应式系统、虚拟DOM、模板编译等核心概念。先掌握Vue基础知识、JavaScript(ES6+)和前端工程化。从源码入口文件开始,研究响应式、虚拟DOM、模板编译、实例方法、全局API及生命周期。理解编译器和渲染器工作原理,实践编写Vue插件,参与开源项目,阅读相关文章教程,持续关注Vue最新动态。这是一个循序渐进、需要耐心和实践的过程。
7 1
|
1天前
|
JavaScript 前端开发
鼠标监视 | 拖拽方块 | Vue
鼠标监视 | 拖拽方块 | Vue
5 0
|
2天前
|
JavaScript
Vue控制是否禁用disabled属性
Vue控制是否禁用disabled属性
7 1
|
2天前
|
JavaScript 前端开发
Vue鼠标悬浮切换图片
Vue鼠标悬浮切换图片
8 0
|
2天前
|
JavaScript 前端开发 内存技术
Vue入门:构建你的第一个Vue应用程序
【4月更文挑战第22天】Vue.js 入门教程:安装 Node.js 和 npm,使用 Vue CLI (`npm install -g @vue/cli`) 创建项目,选择预设或自定义配置。在 `src/components/` 创建 `HelloWorld.vue` 组件,显示数据属性。在 `App.vue` 中引入并注册组件,启动开发服务器 (`npm run serve`) 预览。开始你的 Vue 之旅!
|
2天前
|
JavaScript 前端开发 UED
动画效果:给 Vue 应用添加过渡和动画
【4月更文挑战第22天】Vue 框架提供强大的过渡和动画功能,增强用户体验,创建流畅的用户界面。通过CSS动画、设置过渡属性和自定义过渡,开发者能实现多样化效果。同时,结合组件状态、关注性能并测试优化,确保在不同设备上运行良好,打造引人入胜的应用交互。
|
5天前
|
JavaScript
Ant design Vue 父子组件传递(代码案例--不懂的地方可以私信本博主)
Ant design Vue 父子组件传递(代码案例--不懂的地方可以私信本博主)
10 0
|
5天前
|
JavaScript 前端开发
ant design vue 配置菜单外部打开
ant design vue 配置菜单外部打开
12 0
|
5天前
|
JavaScript
ant design vue 在列表中使用插槽 例如当性别为0的时候在列表中我想显示男
ant design vue 在列表中使用插槽 例如当性别为0的时候在列表中我想显示男
7 0