TinyEditor 篇1:实现工具栏按钮向服务器上传图片

官方文档地址:TinyEditor 官方文档

快速开始

开始之前,当然是最重要的安装环节,有两种安装方式:

通过 NPM 包方式使用

复制代码
npm i @opentiny/fluent-editor

安装好之后,可以在 App.vue 文件或者使用富文本编辑器的文件中,写入:

javascript 复制代码
import '@opentiny/fluent-editor/style.css'
import FluentEditor from '@opentiny/fluent-editor'

完整示例如下:

javascript 复制代码
<template>
  <div class="editor-container">
    <div ref="editorRef" class="editor-inside"></div>
  </div>
</template>

<script setup>
import { onMounted, ref } from 'vue'
import '@opentiny/fluent-editor/style.css'
import FluentEditor from '@opentiny/fluent-editor'

const editorRef = ref(null)
let editorInstance = null

onMounted(() => {
  if (!editorRef.value) return

  editorInstance = new FluentEditor(editorRef.value, {
    theme: 'snow'
  })
})
</script>

通过 CDN 方式使用

我们在 index.html 文件中的 head 区域写入:

html 复制代码
<head>
  <!-- 引入 @opentiny/fluent-editor -->
  <script type="importmap">
    {
      "imports": {
        "@opentiny/fluent-editor": "https://unpkg.com/@opentiny/fluent-editor@3.18.3/index.es.js"
      }
    }
  </script>
  <!-- 引入 @opentiny/fluent-editor 样式 -->
  <link rel="stylesheet" href="https://unpkg.com/@opentiny/fluent-editor@3.18.3/style.css" />
</head>

基于此,我们就可以正式开始编写项目啦!

上传功能

上传的官方示例是可以直接渲染在编辑器中的,我们简单编写一个示例:

javascript 复制代码
<template>
  <div class="editor-container">
    <div ref="editorRef" class="editor-inside"></div>
  </div>
</template>

<script setup>
import { onMounted, ref } from 'vue'
import '@opentiny/fluent-editor/style.css'
import FluentEditor from '@opentiny/fluent-editor'

const editorRef = ref(null)
let editorInstance = null

const TOOLBAR_CONFIG = [
  [{ header: [] }],
  ['bold', 'italic', 'underline', 'link'],
  [{ list: 'ordered' }, { list: 'bullet' }],
  ['clean'],
  ['image']
]

onMounted(() => {
  if (!editorRef.value) return

  editorInstance = new FluentEditor(editorRef.value, {
    theme: 'snow',
    modules: {
      toolbar: {
        container: TOOLBAR_CONFIG
      }
    }
  })
})
</script>

<style scoped>
.editor-container {
  width: 50%;
  display: flex;
  justify-content: center;
  padding-top: 20px;
}

.editor-inside {
  height: 350px;
}

.editor-inside :deep(.ql-container) {
  height: 350px;
}

.editor-inside :deep(.ql-editor) {
  height: 310px;
}
</style>

但在我们日常开发中,上传的内容需要同步到服务器,那么就需要我们自己去控制上传按钮:

我这里的上传步骤是:

1.先使用接口(入参为图片后缀)获取到上传路径及图片路径

2.使用获取到的上传路径进行上传,并返回图片路径进行渲染

javascript 复制代码
<template>
  <div class="editor-container">
    <div ref="editorRef" class="editor-inside"></div>
  </div>
</template>

<script setup>
import { onMounted, ref } from 'vue'
import '@opentiny/fluent-editor/style.css'
import FluentEditor from '@opentiny/fluent-editor'
import axios from 'axios'
import { uploadFile } from '@/model/editor.js' // 这里使用自己的上传接口即可

const editorRef = ref(null)
let editorInstance = null

const TOOLBAR_CONFIG = [
  [{ header: [] }],
  ['bold', 'italic', 'underline', 'link'],
  [{ list: 'ordered' }, { list: 'bullet' }],
  ['clean'],
  ['image']
]

const selectImage = () => {
  const input = document.createElement('input')
  input.type = 'file'
  input.accept = 'image/*'
  input.click()

  input.onchange = async () => {
    const file = input.files[0]
    if (!file) return

    try {
      const url = await uploadImage(file)

      const range = editorInstance.getSelection()
      editorInstance.insertEmbed(range.index, 'image', url)

    } catch (err) {
      console.error('上传失败', err)
    }
  }
}

const uploadImage = async (file) => {
  const ext = file.name.split('.').pop()

  const res = await uploadFile({ ext })

  const resData = res.data
  const uploadUrl = resData.upload_url
  const fileUrl = resData.public_url

  await axios.put(uploadUrl, file, {
    headers: {
      'Content-Type': file.type
    }
  })

  return fileUrl
}

onMounted(() => {
  if (!editorRef.value) return

  editorInstance = new FluentEditor(editorRef.value, {
    theme: 'snow',
    modules: {
      toolbar: {
        container: TOOLBAR_CONFIG,
        handlers: {
          image: selectImage
        }
      }
    }
  })
})
</script>

<style scoped>
.editor-container {
  width: 50%;
  display: flex;
  justify-content: center;
  padding-top: 20px;
}

.editor-inside {
  height: 350px;
}

.editor-inside :deep(.ql-container) {
  height: 350px;
}

.editor-inside :deep(.ql-editor) {
  height: 310px;
}
</style>

通过如上步骤即可成功上传图片,下一篇我们将实现剪贴板粘贴图片至富文本编辑器并上传至服务器的功能。

相关推荐
蚰蜒螟10 分钟前
从 pthread_create 到 thread_native_entry:glibc 如何唤醒 Java 线程
java·开发语言
We་ct13 分钟前
LeetCode 300. 最长递增子序列:两种解法从入门到优化
开发语言·前端·javascript·算法·leetcode·typescript
深海鱼在掘金14 分钟前
Next.js从入门到实战保姆级教程(第一章):导读——建立 Next.js 的认知框架
前端·typescript·next.js
gCode Teacher 格码致知14 分钟前
Python提高: unittest和 pytest的使用方法-由Deepseek产生
开发语言·python·pytest
渔舟小调15 分钟前
P17 | 管理台动态路由:后端返回菜单树,前端运行时注入
前端
aidream123920 分钟前
Linux文件操作-文件打包和压缩(tar/gzip/bzip2/xz/zip)
linux·运维·服务器
小徐_233330 分钟前
uni-app 组件库 Wot UI 2.0 发布了,我们带来了这些改变!
前端·微信小程序·uni-app
Johnstons32 分钟前
网络可观测性落地指南:从“出了问题才排查“到“实时感知全网状态“
开发语言·网络·php
❀͜͡傀儡师35 分钟前
Claude Code 官方弃用 npm 安装方式:原因分析与完整迁移指南
前端·npm·node.js·claude code
️是7838 分钟前
信息奥赛一本通—编程启蒙(3371:【例64.2】 生日相同)
开发语言·c++·算法