ckeditor5和vuedraggle一起使用时,拖拽会导致将内容拖拽到了编辑器里面,如下:
如上图,按住拖拽时,当经过编辑器,编辑器会自动获取焦点,此时松开鼠标,会将拖拽的内容转成文字填入编辑器内。解决方案就是在拖拽时改变富文本状态,禁止编辑,拖拽结束后再恢复可编辑状态。
vuedraggle通过start和end事件监控拖拽发生,在start事件中,调用editor.enableReadOnlyMode( 'my-feature-id' )禁用编辑器,在end事件中,调用editor.disableReadOnlyMode( 'my-feature-id' )来启用编辑器。
具体代码如下:
1、在ckeditor5插件里定义如下方法并暴露出去:
function disableEditor(id) { editor.enableReadOnlyMode(id) } function enableEditor(id) { editor.disableReadOnlyMode(id) } defineExpose({ setData, disableEditor, enableEditor })
2、在调用ckeditor5的页面,监听拖拽的两个事件,分别禁用和启用ckeditor5
<!-- @start="onStart" @end="onEnd",监听事件 --> <draggable :list="ruleForm.articleContent" handle=".move" ghost-class="ghost" chosen-class="chosenClass" animation="300" @start="onStart" @end="onEnd" item-key="fileId"> <template #item="{ element }"> <div class="li"> <el-icon class="move"><el-icon-rank /></el-icon> <el-icon class="close" @click="handleDelete(element)"><el-icon-CloseBold /></el-icon> <div class="flex flex-middle"> <el-image class="img" :src="element.path" :preview-src-list="getPreviewSrcList()" :initial-index="0" preview-teleported /> <div class="right"> <div class="row"> <label>标题</label> <el-input type="text" v-model="element.fileName" style="width:100%" /> </div> <div class="row"> <label>摘要</label> <CkEditor v-model="element.desc" hideWordCountRef height="200px" <!-- 生成随机的ref,因为ckeditor是循环里的,不是一个 --> :ref="(el)=>setItemRef(el, 'editor'+tool.generateUUID())" :toolbarItems="[ 'fontFamily', 'fontSize', 'bold', 'italic', 'underline', 'strikethrough', 'fontBackgroundColor', 'fontColor', 'outdent', 'indent', 'alignment', 'link', 'insertTable' ]" /> </div> <div class="row"> <label>{{ element.type===1 ? '内容' : element.type===2 ? '栏目' : '链接' }}</label> <el-input v-if="element.type===1 || element.type===2" v-model="element.title" type="text" readonly style="width:100%" :placeholder="element.type===1 ? '请选择内容' : '请选择栏目'"> <template #append><el-button @click="handleChoose(element)">选择</el-button></template> </el-input> <el-input v-else v-model="element.url" type="text" placeholder="请输入url,请以http://或https://开头" style="width:100%" /> <el-button class="ml15" :type="element.type===1 ? 'primary' : ''" @click="handleSwitch(element, 1)">链接到内容</el-button> <el-button :type="element.type===2 ? 'primary' : ''" @click="handleSwitch(element, 2)">链接到栏目</el-button> <el-button :type="element.type===3 ? 'primary' : ''" @click="handleSwitch(element, 3)">外部地址</el-button> </div> <div class="row detail"> <label>图片信息</label> <div><span>原名称:</span>{{ element.originalName }}</div> <div><span>大小:</span>{{ instance.proxy.$TOOL.sizeTostr(element.size) }}</div> <div><span>类型:</span>{{ element.fileType }}</div> <!-- <div><span>宽:</span>{{ item.width }}</div> <div><span>高:</span>{{ item.height }}</div> --> </div> </div> </div> </div> </template> </draggable>
3、因为我这是动态渲染出来的多个editor,不得不这么做:
const editorRefs = {} const setItemRef = (el, key) => { if (el) { editorRefs[key] = el } }
4、拖拽开始和结束方法
// 开始拖拽 function onStart() { for(let key in editorRefs) { editorRefs[key].disableEditor(key) } } // 结束拖拽 function onEnd() { for(let key in editorRefs) { editorRefs[key].enableEditor(key) } }