vue3中使用WangEditor 富文本
Vue3 使用 WangEditor 上传图片到七牛云
·
- 安装 WangEditor
npm install wangeditor@4.6.10
- 封装 wangEditor 组件
<template> <div style="border: 1px solid #ccc;"> <Toolbar style="border-bottom: 1px solid #ccc;" :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" /> <Editor style="height: 500px; overflow-y: hidden;" v-model="valueHtml" :defaultConfig="editorConfig" :mode="mode" @onCreated="handleCreated" /> </div> </template> <script> import '@wangeditor/editor/dist/css/style.css' // 引入 css import axios from 'axios' import { message } from 'ant-design-vue' import { Editor, Toolbar } from '@wangeditor/editor-for-vue' // VITE_APP_QINIU_TOKEN 是获取 七牛云token的接口 // VITE_APP_QINIUDOAMIN=https://upload-z2.qiniup.com/ const { VITE_APP_QINIU_TOKEN, VITE_APP_QINIUDOAMIN } = import.meta.env import { watch, onBeforeUnmount, ref, shallowRef, onMounted } from 'vue' export default { name: 'AmEditor', components: { Editor, Toolbar }, props: { content: { type: String, }, }, emits: ['update:content'], setup(props, { emit }) { // 编辑器实例,必须用 shallowRef const editorRef = shallowRef() // 内容 HTML const valueHtml = ref(props.content) // 模拟 ajax 异步获取内容 onMounted(() => { valueHtml.value = '' }) // 上传数据 watch( () => valueHtml.value, (val) => { emit('update:content', val) }, { deep: true, }, ) // 工具栏配置 const toolbarConfig = { toolbarKeys: [ // 菜单 key 'headerSelect', 'bold', // 加粗 'italic', // 斜体 'through', // 删除线 'underline', // 下划线 'bulletedList', // 无序列表 'numberedList', // 有序列表 'color', // 文字色彩 'insertLink', // 插入链接 'fontSize', // 字体大小 'lineHeight', // 行高 'uploadImage', // 上传图片 'delIndent', // 缩进 'indent', // 增进 'deleteImage', //删除图片 'divider', // 分割线 'insertTable', // 插入表格 'justifyCenter', // 居中对齐 'justifyJustify', // 两端对齐 'justifyLeft', // 左对齐 'justifyRight', // 右对齐 'undo', // 撤销 'redo', // 重做 'clearStyle', // 革除格局 'fullScreen', // 全屏 ], } const editorConfig = { placeholder: '请输出内容...', // 配置默认提醒 // readOnly: true, MENU_CONF: { // 配置上传服务器地址 uploadImage: { // 小于该值就插入 base64 格局(而不上传),默认为 0 base64LimitSize: 5 * 1024, // 5kb // 单个文件的最大体积限度,默认为 2M // maxFileSize: 1 * 1024 * 1024, // 1M // // 最多可上传几个文件,默认为 100 // maxNumberOfFiles: 5, // 抉择文件时的类型限度,默认为 ['image/*'] 。如不想限度,则设置为 [] allowedFileTypes: ['image/*'], // 自定义上传 async customUpload(file, insertFn) { // 文件上传 // const formData = new FormData() // formData.set('file', file) const result = await customUpload(file) // 插入到富文本编辑器中,主见这里的三个参数都是必填的,要不然控制台报错:typeError: Cannot read properties of undefined (reading 'replace') insertFn(result, result, result) }, }, }, } // 组件销毁时,也及时销毁编辑器 onBeforeUnmount(() => { const editor = editorRef.value if (editor == null) return editor.destroy() }) const handleCreated = (editor) => { editorRef.value = editor // 记录 editor 实例,重要! } // 处理上传参数 const paramsImg = (file) => { return new Promise((resolve, reject) => { let fileName = file.name let key = `aimei/img/${fileName}` let data = { data: { id: 8, key: key, secret: '这个密钥是公司运维给的', }, } resolve(data) }) } // 获取七牛云上传token const getQiniuToken = (data) => { return new Promise((resolve, _reject) => { axios.post(VITE_APP_QINIU_TOKEN, data).then((res) => { resolve(res) }) }) } // 上传图片获取在线链接 const customUpload = (file) => { return new Promise((resolve, _reject) => { paramsImg(file) .then((data) => { getQiniuToken(data) .then((res) => { if ( res && res.data.result_code === 0 && res.data.result_msg.includes('OK') ) { let domain = res.data.data.token_info.domain const formData = new FormData() formData.append('file', file.file) formData.append('key', res.data.data.key) formData.append('token', res.data.data.token_info.token) axios .post(`${VITE_APP_QINIUDOAMIN}`, formData, { headers: { 'Content-Type': 'multipart/form-data', }, }) .then((response) => { if (response.status == 200) { const url = `${location.protocol}//${domain}/${response.data.key}` // 上传成功之后将上传的状态改为done return resolve(url) } }) .catch((res) => { return _reject(res) message.error('上传失败') }) } }) .finally(() => {}) }) .catch((error) => console.log('error', error)) }) } return { editorRef, valueHtml, mode: 'simple', // 或 'simple' toolbarConfig, editorConfig, handleCreated, } }, } </script> <style lang="scss" scoped></style>
- 使用的方法
引入这个组件,例如 <edit v-model:content="你的变量" /> 就可以了
更多推荐
已为社区贡献17条内容
所有评论(0)