Vue3使用vue-draggable拖拽排序时出现空值读取错误
Vue3中vue-draggable拖动排序异常及TypeError问题解决
拖动组件调整顺序时无法正常切换,同时抛出以下错误:
Uncaught TypeError: Cannot read properties of null (reading "element")Uncaught TypeError: Cannot read properties of null (reading "index")
相关代码如下:
模板部分:
<draggable v-model="modules" item-key="id" handle=".module-handle" animation="200"> <template #item="{ element }"> <component v-if="element && registry[element.type]" :is="registry[element.type]" v-bind="element.props" :uid="uid" :edit="profileEdit" /> </template> </draggable>
脚本部分:
const registry = { bio: defineAsyncComponent(() => import('./components/Biography.vue')), media: defineAsyncComponent(() => import('./components/Media.vue')), links: defineAsyncComponent(() => import('./components/Links.vue')), music: defineAsyncComponent(() => import('./components/Music.vue')) } const modules = ref([ { id: 1, type: 'bio', props: {} }, { id: 2, type: 'media', props: {} }, { id: 3, type: 'links', props: {} }, { id: 4, type: 'music', props: {} } ]);
问题原因
拖动过程中,vue-draggable会临时生成虚拟元素用于占位或过渡,此时element可能为null,或者registry[element.type]匹配失败,导致<component>被v-if销毁。DOM结构的突然破坏会让draggable组件无法读取到预期的元素和索引,从而抛出TypeError。
解决办法
方案1:用v-show替代v-if
v-show仅控制元素的显示/隐藏,不会销毁DOM,能保持draggable所需的DOM结构完整:
<draggable v-model="modules" item-key="id" handle=".module-handle" animation="200"> <template #item="{ element }"> <component v-show="element && registry[element.type]" :is="registry[element.type]" v-bind="element.props" :uid="uid" :edit="profileEdit" /> </template> </draggable>
方案2:将条件判断移至组件内部
确保<component>始终被渲染,把显示逻辑放到每个异步组件内部:
<draggable v-model="modules" item-key="id" handle=".module-handle" animation="200"> <template #item="{ element }"> <component :is="registry[element.type] || 'div'" v-bind="element.props" :uid="uid" :edit="profileEdit" :element="element" /> </template> </draggable>
以Biography.vue为例,内部添加显示控制:
<template> <div v-show="element?.type === 'bio'"> <!-- 组件原有内容 --> </div> </template> <script setup> const props = defineProps(['element']) </script>
额外检查
确认item-key="id"对应的每个modules项的id值唯一且稳定,避免拖动过程中key值变化导致的DOM异常。
内容的提问来源于stack exchange,提问作者crxtic
相关产品推荐
相关产品推荐

