前言

在做项目的过程中,有时候会遇到一些复杂文本的编辑,这个时候就需要用到富文本编辑器来实现自己想要的效果。例如:文章的发布、文章详情的展示等。富文本编辑器的底层原理是什么呢?以下是个人的理解:说白了,富文本编辑器的内容最终还是要展示在浏览器上,那既然展示在浏览器上,那就还是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>

GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891 Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐