Closed JaneYork closed 2 months ago
<template>
<div>
<!-- <div>-->
<!-- <button @click="printEditorHtml">print html</button>-->
<!-- <button @click="getEditorText">print text</button>-->
<!-- </div>-->
<div style="border: 1px solid #ccc; margin-top: 10px">
<!-- 工具栏 -->
<Toolbar style="border-bottom: 1px solid #ccc" :editor="editor" :defaultConfig="toolbarConfig" />
<!-- 编辑器 -->
<Editor
style="height: 400px; overflow-y: hidden"
:defaultConfig="editorConfig"
v-model="html"
@onChange="onChange"
@onCreated="onCreated"
/>
</div>
<!-- <div style="margin-top: 10px">-->
<!-- <textarea v-model="html" readonly style="width: 100%; height: 200px; outline: none"></textarea>-->
<!-- </div>-->
</div>
</template>
<script>
import { Editor, Toolbar } from '@wangeditor-next/editor-for-vue2'
import storage from 'store'
import { ACCESS_TOKEN } from '@/store/mutation-types'
export default {
name: 'WangNextEditor',
props: {
value: {
type: String,
default: '',
},
},
components: { Editor, Toolbar },
data() {
return {
uploadImgUrl: process.env.VUE_APP_BASE_API + '/common/upload',
headers: {
Authorization: 'Bearer ' + storage.get(ACCESS_TOKEN),
Accept: 'application/json, text/plain, */*'
},
editor: null,
html: '',
toolbarConfig: {
// toolbarKeys: [ /* 显示哪些菜单,如何排序、分组 */ ],
// excludeKeys: [ /* 隐藏哪些菜单 */ ],
},
editorConfig: {
placeholder: '请输入内容...',
// autoFocus: false,
// 所有的菜单配置,都要在 MENU_CONF 属性下
MENU_CONF: {},
},
}
},
created() {
this.editorConfig.MENU_CONF['uploadImage'] = {
server: this.uploadImgUrl,
// server: '/api/upload-img-10s', // test timeout
// server: '/api/upload-img-failed', // test failed
// server: '/api/xxx', // test 404
timeout: 5 * 1000, // 5s
fieldName: 'file',
meta: { token: 'xxx', a: 100 },
metaWithUrl: true, // join params to url
headers: this.headers,
maxFileSize: 10 * 1024 * 1024, // 10M
base64LimitSize: 1 * 1024, // insert base64 format, if file's size less than 5kb
// maxNumberOfSize: 1,
onBeforeUpload(file) {
console.log('onBeforeUpload', file)
return file // will upload this file
// return false // prevent upload
},
onProgress(progress) {
console.log('onProgress', progress)
},
onSuccess(file, res) {
console.log('onSuccess', file, res)
},
onFailed(file, res) {
alert(res.message)
console.log('onFailed', file, res)
},
onError(file, err, res) {
alert(err.message)
console.error('onError', file, err, res)
},
customInsert(res, insertFn) {
console.log('customInsert', res)
const imgInfo = res.data
const { url, alt, href } = imgInfo
if (!url) throw new Error(`Image url is empty`)
console.log('Your image url ', url)
insertFn(url, 'pusdn', '')
},
// customUpload(file, insertFn) {
// console.log('customUpload', file)
// return new Promise((resolve) => {
// // Simulate async insert image
// setTimeout(() => {
// const src = `https://www.baidu.com/img/flexible/logo/pc/result@2.png?r=${Math.random()}`
// insertFn(src, 'baidu logo', src)
// resolve('ok')
// }, 500)
// })
// },
// customBrowseAndUpload(insertFn) {
// alert('Custom browse and upload')
// // Simulate async insert image
// setTimeout(() => {
// const src = 'https://www.baidu.com/img/flexible/logo/pc/result@2.png'
// insertFn(src, 'baidu logo', src) // insert a image
// }, 500)
// },
}
},
methods: {
onCreated(editor) {
this.editor = Object.seal(editor) // 【注意】一定要用 Object.seal() 否则会报错
console.log(this.editor.id)
},
onChange(editor) {
console.log('onChange', editor.getHtml()) // onChange 时获取编辑器最新内容
this.$emit('input', editor.getHtml())
},
getEditorText() {
const editor = this.editor
if (editor == null) return
console.log(editor.getText()) // 执行 editor API
},
printEditorHtml() {
const editor = this.editor
if (editor == null) return
console.log(editor.getHtml()) // 执行 editor API
},
},
watch: {
value: {
handler (val) {
// if (val !== this.currentValue) {
// this.currentValue = val === null ? '' : val
// if (this.editor) {
// this.editor.txt.html(this.currentValue)
// }
// }
// if (this.editor) {
// // 假设你有一个方法来设置编辑器的HTML
// this.editor.setContent(this.html = newVal)
// }
this.html = val
},
immediate: true
}
},
mounted() {
// 模拟 ajax 请求,异步渲染编辑器
// setTimeout(() => {
// this.html = '<p>Ajax 异步设置内容 HTML</p>'
// }, 1500)
},
beforeDestroy() {
const editor = this.editor
if (editor == null) return
editor.destroy() // 组件销毁时,及时销毁 editor ,重要!!!
},
}
</script>
<style src="@wangeditor-next/editor/dist/css/style.css"></style>
<WangNextEditor v-model="form.details" />
<WangNextEditor v-model="form.details2" />
<WangNextEditor v-model="form.details3" />
@cycleccc
多编辑器都有的问题,现在手头上正在处理这个,要把多个编辑器创的监听隔离开,需要花点时间处理,可以的话先尝试在项目层面隔离多个编辑器之间的影响。
多编辑器都有的问题,现在手头上正在处理这个,要把多个编辑器创的监听隔离开,需要花点时间处理,可以的话先尝试在项目层面隔离多个编辑器之间的影响。
具体如何操作呢,有相关文档吗
尽量隔离开或是多编辑器切换时销毁重建,这属于 hack 手段,你可以都试下🌚
尽量隔离开或是多编辑器切换时销毁重建,这属于 hack 手段,你可以都试下🌚
一个页面多个编辑器,上面一个,下面一个,上面最大化后,样式错误。 演示站点也有这个问题
@cycleccc
我更新了 5.3.14 版本 你可以试试现在复制粘贴还有没有问题。
样式错误这个可以另提一个 issue,这应该和过往的改动无关,估计是 wangeditor 历史遗留问题,我们在另一个 issue 可以讨论下。
我更新了 5.3.14 版本 你可以试试现在复制粘贴还有没有问题。
"@wangeditor-next/editor": "^5.3.14",
"@wangeditor-next/editor-for-vue2": "^1.0.2",这个需要更新吗
😋node至少18 error nanoid@5.0.7: The engine "node" is incompatible with this module. Expected version "^18 || >=20". Got "16.20.1" error Found incompatible module.
vue2包 不用改,这几个 框架包 只是包了层皮,做个中间层传输数据给 editor 这个包
nanoid 是前段时间升的,有人在 wangEditor 原项目反馈说 nanoid 版本太低,报错了,我就升了新版,node 16 可能确实不适配 意思是 你的node 版本已经 18 了,还是报错 16 吗,如果是的话那就得看看了,可能还得升其它依赖了nanoid 的包的版本。🤯
nanoid 是前段时间升的,有人在 wangEditor 原项目反馈说 nanoid 版本太低,报错了,我就升了新版,node 16 可能确实不适配 意思是 你的node 版本已经 18 了,还是报错 16 吗,如果是的话那就得看看了,可能还得升其它依赖了nanoid 的包的版本。🤯
不不,我的是node16。
另外, https://cycleccc.github.io/docs/guide/toolbar-config#excludekeys vue2如何排除某些菜单?有示例吗
排除菜单就按文档示例的来就行,创建菜单时加入对应配置即可
bug 描述
【BUG】vue2多个编辑器复制粘贴报错
你预期的样子是?
控制台报错
系统和浏览器及版本号
wangEditor-next 版本
demo 能否复现该 bug ?
能
在线 demo