如何使用vuedraggable实现Bootstrap b-table表格行可拖拽功能
实现方案
你已经引入了vuedraggable,只需要通过b-table的自定义tbody插槽接入拖拽能力即可,具体修改如下:
1. 模板部分修改
在原有<b-table>标签内增加tbody自定义插槽,嵌套draggable组件包裹行渲染逻辑,原有cell(actions)插槽可以直接删除,已整合到下方自定义行逻辑中:
<b-table fixed outlined striped hover stacked="md" :items="items" :fields="fields"> <!-- 新增自定义tbody插槽 --> <template #tbody> <draggable v-model="localItems" tag="tbody" :item-key="row => getModalId(row)" handle=".drag-handle" <!-- 可选,设置仅拖拽把手可拖动,删除则整行可拖 --> animation="300" <!-- 可选,拖拽动画时长 --> @end="onDragEnd" > <template #item="{ element: row }"> <tr> <!-- 遍历所有字段渲染单元格 --> <td v-for="(field, index) in fields" :key="index"> <!-- 处理操作列特殊逻辑 --> <div v-if="field.key === 'actions'" class="text-md-right float-right"> <!-- 拖拽把手,仅编辑权限可见 --> <font-awesome-icon icon="grip-vertical" class="drag-handle mr-2" v-if="!approved && $store.state.permissions.location_permission > 10"/> <b-button-group size="sm"> <slot :item="row"></slot> <b-button v-b-tooltip.hover title="Bearbeiten" v-if="$store.state.permissions.location_permission > 10 && !approved" type="button" variant="primary" @click="$emit('changeMode',row)" > <font-awesome-icon icon="edit"/> </b-button> <b-button @click="showModal(row)" v-b-tooltip.hover title="Löschen" v-if="$store.state.permissions.location_permission > 10 && !approved" type="button" variant="danger" > <font-awesome-icon icon="trash"/> </b-button> <safety-modal :modal-id="`safety-modal-${getModalId(row)}`" @removeItem="removeItem(row)" ></safety-modal> </b-button-group> </div> <!-- 普通字段直接渲染对应值 --> <span v-else>{{ row[field.key] }}</span> </td> </tr> </template> </draggable> </template> </b-table>
2. script部分修改
新增本地临时数组存储拖拽状态,避免直接修改props,拖拽结束后同步结果到父组件:
<script> import BaseSafetyModal from '@/components/Base/BaseSafetyModal'; import draggable from "vuedraggable"; export default { components: { 'safety-modal': BaseSafetyModal, draggable }, props: { fields: { type: Array, required: true }, items: { type: Array, required: true }, approved: { type: Boolean, default: false } }, data() { return { // 克隆props数据作为本地拖拽状态数据源 localItems: [...this.items] } }, watch: { // 监听父组件数据源变化,同步本地数据 items(newVal) { this.localItems = [...newVal] } }, methods: { // 新增拖拽结束回调,同步排序结果到父组件 onDragEnd() { this.$emit('update:items', [...this.localItems]) }, getModalId (item) { let name = Object.keys(item).find( itemKeys => itemKeys.indexOf('id') > -1 && itemKeys !== 'headline_id' && itemKeys !== 'revision_id' && itemKeys !== 'building_id' ); if ( Object.keys(item).indexOf('geometry_id') > -1 && Object.keys(item).indexOf('level_id') > -1 ) name = 'level_id'; return `${name}-${item[name]}`; }, showModal (item) { this.$root.$emit('bv::show::modal', `safety-modal-${this.getModalId(item)}`); }, removeItem (item) { this.$emit('removeItem', item); this.$root.$emit('bv::hide::modal', `safety-modal-${this.getModalId(item)}`); } } }; </script>
3. 父组件适配
父组件调用该表格组件时,添加.sync修饰符接收排序后的数据源即可:
<your-table-component :items.sync="你的数据源变量" :fields="你的字段配置" :approved="审批状态变量" />
内容的提问来源于stack exchange,提问作者Pouria1991
相关产品推荐
相关产品推荐

