首页 > 建站教程 > 编辑器、IDE >  解决vuedraggle拖拽时内容将内容拖拽到ckeditor5的编辑框内正文

解决vuedraggle拖拽时内容将内容拖拽到ckeditor5的编辑框内

ckeditor5和vuedraggle一起使用时,拖拽会导致将内容拖拽到了编辑器里面,如下:

ckeditor5ckeditor5

ckeditor5


如上图,按住拖拽时,当经过编辑器,编辑器会自动获取焦点,此时松开鼠标,会将拖拽的内容转成文字填入编辑器内。解决方案就是在拖拽时改变富文本状态,禁止编辑,拖拽结束后再恢复可编辑状态。


vuedraggle通过start和end事件监控拖拽发生,在start事件中,调用editor.enableReadOnlyMode( 'my-feature-id' )禁用编辑器,在end事件中,调用editor.disableReadOnlyMode( 'my-feature-id' )来启用编辑器。


具体代码如下:

1、在ckeditor5插件里定义如下方法并暴露出去:

01function disableEditor(id) {
02  editor.enableReadOnlyMode(id)
03}
04function enableEditor(id) {
05  editor.disableReadOnlyMode(id)
06}
07defineExpose({
08  setData,
09  disableEditor,
10  enableEditor
11})


2、在调用ckeditor5的页面,监听拖拽的两个事件,分别禁用和启用ckeditor5

01<!-- @start="onStart" @end="onEnd",监听事件 -->
02<draggable :list="ruleForm.articleContent" handle=".move" ghost-class="ghost" chosen-class="chosenClass" animation="300" @start="onStart" @end="onEnd" item-key="fileId">
03  <template #item="{ element }">
04    <div class="li">
05      <el-icon class="move"><el-icon-rank /></el-icon>
06      <el-icon class="close" @click="handleDelete(element)"><el-icon-CloseBold /></el-icon>
07      <div class="flex flex-middle">
08        <el-image class="img" :src="element.path" :preview-src-list="getPreviewSrcList()" :initial-index="0" preview-teleported />
09        <div class="right">
10          <div class="row">
11            <label>标题</label>
12            <el-input type="text" v-model="element.fileName" style="width:100%" />
13          </div>
14          <div class="row">
15            <label>摘要</label>
16            <CkEditor
17              v-model="element.desc"
18              hideWordCountRef
19              height="200px"
20              <!-- 生成随机的ref,因为ckeditor是循环里的,不是一个 -->
21              :ref="(el)=>setItemRef(el, 'editor'+tool.generateUUID())"
22              :toolbarItems="[
23                'fontFamily', 'fontSize', 'bold', 'italic', 'underline', 'strikethrough',
24                'fontBackgroundColor', 'fontColor', 'outdent', 'indent', 'alignment',
25                'link', 'insertTable'
26              ]"
27            />
28          </div>
29          <div class="row">
30            <label>{{ element.type===1 ? '内容' : element.type===2 ? '栏目' : '链接' }}</label>
31            <el-input v-if="element.type===1 || element.type===2" v-model="element.title" type="text" readonly style="width:100%" :placeholder="element.type===1 ? '请选择内容' : '请选择栏目'">
32              <template #append><el-button @click="handleChoose(element)">选择</el-button></template>
33            </el-input>
34            <el-input v-else v-model="element.url" type="text" placeholder="请输入url,请以http://https://开头" style="width:100%" />
35            <el-button class="ml15" :type="element.type===1 ? 'primary' : ''" @click="handleSwitch(element, 1)">链接到内容</el-button>
36            <el-button :type="element.type===2 ? 'primary' : ''" @click="handleSwitch(element, 2)">链接到栏目</el-button>
37            <el-button :type="element.type===3 ? 'primary' : ''" @click="handleSwitch(element, 3)">外部地址</el-button>
38          </div>
39          <div class="row detail">
40            <label>图片信息</label>
41            <div><span>原名称:</span>{{ element.originalName }}</div>
42            <div><span>大小:</span>{{ instance.proxy.$TOOL.sizeTostr(element.size) }}</div>
43            <div><span>类型:</span>{{ element.fileType }}</div>
44            <!-- <div><span>宽:</span>{{ item.width }}</div>
45            <div><span>高:</span>{{ item.height }}</div> -->
46          </div>
47        </div>
48      </div>
49    </div>
50  </template>
51</draggable>


3、因为我这是动态渲染出来的多个editor,不得不这么做:

1const editorRefs = {}
2const setItemRef = (el, key) => {
3  if (el) {
4    editorRefs[key] = el
5  }
6}


4、拖拽开始和结束方法

01// 开始拖拽
02function onStart() {
03  for(let key in editorRefs) {
04    editorRefs[key].disableEditor(key)
05  }
06}
07// 结束拖拽
08function onEnd() {
09  for(let key in editorRefs) {
10    editorRefs[key].enableEditor(key)
11  }
12}