【Vue】富文本编辑器组件

前言

在做项目的过程中,有时候会遇到一些复杂文本的编辑,这个时候就需要用到富文本编辑器来实现自己想要的效果。例如:文章的发布、文章详情的展示等。富文本编辑器的底层原理是什么呢?以下是个人的理解:说白了,富文本编辑器的内容最终还是要展示在浏览器上,那既然展示在浏览器上,那就还是html、css。当富文本编辑器是纯文字的时候,那么最终展示出来的就是html里的就是纯文本,没有任何标签和样式,当你想在富文本里给文本一个样式时,要么通过html标签,要么通过css样式,举个例子,想给文本加粗:
第一种方式: <b>文本</b>
第二种方式:<span style="font-weight: bold;">文本</span>
常用的富文本编辑器有:summernotevue-quill-editorwangEditor ,本文针对wangEditor的使用做一个基本的介绍。

安装

安装 editor

npm install @wangeditor/editor --save
yarn add @wangeditor/editor

安装 Vue3 组件

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

使用

封装Editor.vue组件

<template>
  <div class="editor-container">
    <Toolbar class="toolbar" :editor="editorRef" :mode="mode" />
    <Editor
      v-model="state.value"
      :default-config="state.config"
      :mode="mode"
      @on-created="handleCreated"
      @on-change="handleChange"
    />
  </div>
</template>

<script setup lang="ts">
import { reactive, onBeforeUnmount, shallowRef, watch } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import '@wangeditor/editor/dist/css/style.css' // 引入 css (在显示富文本内容时也需要引入该)

const props = defineProps({
  // 模式,可选 <default|simple>
  mode: {
    type: String,
    default: 'default'
  },
  // 是否禁用
  disable: {
    type: Boolean,
    default: false
  },
  // 内容框默认 placeholder
  placeholder: {
    type: String,
    default: '请输入内容...'
  },
  // 双向绑定,用于获取 editor.getHtml()
  getHtml: {
    type: String,
    default: ''
  },
  // 双向绑定,用于获取 editor.getText()
  getText: {
    type: String,
    default: ''
  }
})

// 定义子组件向父组件传值/事件
const emit = defineEmits(['update:getHtml', 'update:getText'])

// 编辑器实例,必须用 shallowRef
const editorRef = shallowRef()

const state = reactive({
  config: {
    placeholder: props.placeholder
  },
  value: props.getHtml
})

// 编辑器回调函数
const handleCreated = (editor: any) => {
  editorRef.value = editor
  if (props.disable) {
    editor.disable()
  }
}
// 编辑器内容改变时
const handleChange = (editor: any) => {
  emit('update:getHtml', editor.getHtml())
  emit('update:getText', editor.getText())
}

onBeforeUnmount(() => {
  // 组件销毁时,也及时销毁编辑器
  const editor = editorRef.value
  if (editor == null) {
    return
  }
  editor.destroy()
})

// 监听是否禁用改变
watch(
  () => props.disable,
  value => {
    const editor = editorRef.value
    if (editor == null) {
      return
    }
    value ? editor.disable() : editor.enable()
  },
  {
    deep: true
  }
)
// 监听双向绑定值改变,用于回显
watch(
  () => props.getHtml,
  value => {
    state.value = value
  },
  { deep: true }
)
</script>

<style scoped lang="scss">
.editor-container {
  border: 1px solid #ccc;
  .toolbar {
    border-bottom: 1px solid #ccc;
  }
  :deep(.w-e-text-container) {
    height: 320px;
    overflow-y: hidden;
  }
}
</style>

调用Editor.vue组件

<template>
  <div class="container">
    <editor v-model:get-html="data.htmlVal" v-model:get-text="data.textVal"></editor>
  </div>
</template>

<script setup lang="ts">
import { reactive, defineAsyncComponent } from 'vue'
const Editor = defineAsyncComponent(() => import('@/components/Common/Editor.vue'))

const data = reactive({
  htmlVal: '',
  textVal: ''
})
</script>

<style scoped lang="scss"></style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值