Как сделать колонки в таблице Element Plus перетаскиваемыми?

Я работаю над проектом, где использую таблицу el-table из библиотеки Element Plus в сочетании с draggable для перестановки колонок. Однако у меня возникают ошибки: <br/> Unhandled error during execution of mounted hook <br/> Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'updated'). <br/> <br/> Вот мой код: <br/> <pre><code class="javascript">&lt;template&gt;
    &lt;el-table :data="tableData" style="width: 100%"&gt;
        &lt;draggable
              tag="el-table-header"
              :list="visible_columns_new"
              :component-data="getComponentData()"
              item-key="id"
            &gt;
                &lt;el-table-column v-for="item in tableColumns" :prop="item.prop" :key="item.prop" :label="item.label"&gt;
                     &lt;template #header="scope"&gt; &lt;span style="cursor: move"&gt;⠿&lt;/span&gt; {{ scope.column.label }} &lt;/template&gt;
                     &lt;template #default="scope"&gt; &lt;span&gt;{{ scope.row[item.prop]}}&lt;/span&gt; &lt;/template&gt;
                &lt;/el-table-column&gt;
        &lt;/draggable&gt;
    &lt;/el-table&gt;
&lt;/template&gt;

&lt;script setup lang="ts"&gt;
import { ref } from 'vue'
import draggable from 'vuedraggable'

const tableColumns = [
    { id: 1, prop: 'date',  label: 'Date' },
    { id: 2, prop: 'name',  label: 'Name' },
    { id: 3, prop: 'state',  label: 'State' },
    { id: 4, prop: 'city',  label: 'City' },
]
const tableData = ref([
  {
    date: '2016-05-03',
    name: 'Tom',
    state: 'California',
    city: 'Los Angeles',
  },
])

const getComponentData = () =&gt; {
  return {
    wrap: true
  }
}
&lt;/script&gt;</code></pre> <br/> <br/> Как я могу решить эту проблему?
  • 3 октября 2024 г. 14:14
Ответы на вопрос 2
Для того чтобы сделать колонки в таблице Element Plus перетаскиваемыми с помощью `vuedraggable`, необходимо учитывать, что изменения в порядке колонок должны быть связаны с самим массивом колонок, который хранит их порядок. Также убедитесь, что используете правильную структуру для перетаскивания и правильно передаете необходимые свойства. 

В вашем коде нужно внести несколько изменений:

1. Вам нужно будет отслеживать порядок колонок и обновлять их в массиве `tableColumns`.
2. Поле `:list` у вашего компонента `draggable` должно ссылаться на массив колонок, а не на массив видимых колонок.

Вот исправленный пример вашего кода:

```html
<template>
    <el-table :data="tableData" style="width: 100%">
        <draggable
            tag="template"
            :list="tableColumns"
            item-key="id"
            @end="updateColumns">
            <template v-for="item in tableColumns" :key="item.id">
                <el-table-column
                    :prop="item.prop"
                    :key="item.prop"
                    :label="item.label">
                    <template #header="scope">
                        <span style="cursor: move">⠿</span> {{ scope.column.label }}
                    </template>
                    <template #default="scope">
                        <span>{{ scope.row[item.prop] }}</span>
                    </template>
                </el-table-column>
            </template>
        </draggable>
    </el-table>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import draggable from 'vuedraggable'

const tableColumns = ref([
    { id: 1, prop: 'date', label: 'Date' },
    { id: 2, prop: 'name', label: 'Name' },
    { id: 3, prop: 'state', label: 'State' },
    { id: 4, prop: 'city', label: 'City' },
]);

const tableData = ref([
  {
    date: '2016-05-03',
    name: 'Tom',
    state: 'California',
    city: 'Los Angeles',
  },
]);

const updateColumns = (evt: any) => {
    console.log('Columns reordered:', evt);
    // Теперь вы можете обновить состояние компонентов или выполнить дополнительные действия
}
</script>

<style>
/* Добавьте необходимые стили */
</style>
```

В данной реализации:

- Я изменил `tag` на `template`, чтобы можно было перетаскивать элементы в шаблоне.
- `item-key` принимает свойство `id`, чтобы различать ваши колонки.
- Добавлен метод `updateColumns`, который можно использовать для отслеживания изменений при перетаскивании колонок. Вы можете дописать логику, если нужно обновить состояние.

Убедитесь, что у вас корректно подключен `vuedraggable` и все необходимые зависимости.
Можно попробовать использовать sortable.js : 

<el-table
  ref="table"
  ...
>
  ...

const table = ref();

onMounted(() => { 
  new Sortable(table.value.$el.querySelector('thead tr'), {
    handle: 'span',
    onEnd(e) {
      columns.value.splice(e.newIndex, 0, columns.value.splice(e.oldIndex, 1)[0]);
    },
  });
});
Похожие вопросы