使用Vue.Draggable.next拖拽后排序恢复的问题

分类: 编程
日期: 2022-07-29
浏览: 311

最近在使用Laravel + Vue开发一个小项目时,需要用到拖拽排序功能,于是就用了vue.draggable.next这个组件,在使用的过程中遇到了一些小问题,在此记录一下。

版本问题

一开始没有注意,安装的是Vue.Draggable,使用的时候一直报错,搞得我云里雾里的,后来去GitHub上看了一下README才发现,Vue.Draggable适配的是Vue2.0,Vue3要使用vue.draggable.next。

正确使用组件的注意点

官方示例

<draggable v-model="myArray" tag="transition-group" item-key="id">
  <template #item="{element}">
      <div> {{element.name}} </div>
  </template>
</draggable>

注意点:

  • 不需要v-for循环,v-model填入数组后,会自动循环。
  • item-key要添加,不然控制台会发出警告。
  • tag要正确使用,表示要把组件渲染成的HTML Node,默认为div。
  • 要使用<template>#item必填,值一定是element不可修改。

错误示范:

  1. 使用了v-for。
<draggable v-model="categories" tag="tbody" item-key="id" @end="onEnd">
    <template #item="{element}">
        <tr v-for="category in categories">
            <td>{{ category.sort }}</td>
            <td>{{ category.name }}</td>
        </tr>
    </template>
</draggable>

数据被重复循环

  1. 未填写item-key。

  1. 未正确使用tag样式会混乱,组件默认会渲染成div,但是子节点是tr,父标签为tbody才能正确显示,所以此处要添加 tag="tbody"
<draggable v-model="categories" item-key="id" @end="onEnd">
    <template #item="{element, index}">
        <tr>
            <td>{{ index + 1 }}</td>
            <td>{{ element.name }}</td>
        </tr>
    </template>
</draggable>

数据挤在一个单元格中

  1. <template>中的element改为其它,页面直接报错。
<draggable v-model="categories" tag="tbody" item-key="id" @end="onEnd">
    <template #item="{item}">
        <tr>
            <td>{{ item.sort }}</td>
            <td>{{ item.name }}</td>
        </tr>
    </template>
</draggable>

item未正确拿到数组中的对象

无法排序的问题

问题如下,条目可以拖拽,但是释放的瞬间就恢复原位了。

代码如下

const categories = usePage().props.value.categories

usePage()是Inertiajs的用法,作用是接收从后端传递过来的数据,并响应式代理,与Vue的reactive一致。

<draggable v-model="categories" tag="tbody" item-key="id" @end="onEnd">
    <template #item="{element, index}">
        <tr>
            <td>{{ element.sort }}</td>
            <td>{{ element.name }}</td>
            <td>
                <n-image width="40" height="40" :src="element.icon" v-if="element.icon"/>
            </td>
            <td>{{ element.slug }}</td>
            <td>{{ element.created_at }}</td>
            <td>
                <n-space>
                    <n-button size="small" type="primary" ghost @click="edit(element)">编辑</n-button>
                    <n-button size="small" type="error" ghost @click="destroy(element)">删除</n-button>
                </n-space>
            </td>
        </tr>
    </template>
</draggable>

模板部分的代码没有任何问题,其实问题就出在了usePage().props.value.categories上,将其换成reactive后,依然无法正确排序,换成ref之后就可以了。

修改后的代码

const categories = ref(usePage().props.value.categories)
版权声明
作者:不二
来源:不二博客
文章版权归作者所有,未经允许请勿转载。
共有 0 条评论
赶快发表评论吧~
发表评论