首页 > 建站教程 > 编辑器、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插件里定义如下方法并暴露出去:

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)
  }
}