使用#sortablejs插件对表格中拖拽行排序#Vue3#后端接口数据

news2024/11/15 21:52:54

使用#sortablejs对表格中拖拽行排序#Vue3#后端接口数据

*效果:
在这里插入图片描述

拖动表格行排序

首先安装插件sortable

npm install sortablejs --save

代码:

<template>
  <!-- sortable.js 进行表格排序 -->
  <!-- 演示地址 -->
  <div class="dem-add">
    <!-- Search start -->
    <div class="dem-title">
      <p>演示地址</p>
      <el-input
        class="query-input"
        v-model="tableForm.demoDevice"
        placeholder="搜索"
        @keyup.enter="handleQueryName"
      >
        <template #prefix>
          <el-icon class="el-input__icon"><search /></el-icon>
        </template>
      </el-input>
      <el-button type="primary" :icon="Plus" circle @click="handleAdd" />
    </div>
    <!-- Search end -->
    <!-- Table start -->
    <div class="bs-page-table">
      <el-table :data="tableData" :row-key="(record) => record.sort">
        <el-table-column prop="sort" label="排序" width="60" />
        <el-table-column prop="demoDevice" label="演示端" width="150" />
        <el-table-column prop="address" label="地址" width="180" />
        <el-table-column prop="description" label="特殊说明" width="180" />
        <el-table-column prop="fileIds" label="附加" width="100">
          <template #default="scope">
            <a
              :href="`http://192.168.1.214:5050${scope.row.files[0].filePath}`"
              style="color: blue; text-decoration: none"
              target="_blank"
            >
              <el-button
                circle
                size="default"
                type="default"
                :icon="FolderChecked"
              ></el-button>
            </a>
          </template>
        </el-table-column>
        <el-table-column fixed="right" label="操作" width="100">
          <template #default="scope">
            <el-button
              type="danger"
              @click="handleRowDel(scope.$index)"
              :icon="Delete"
              circle
            />
          </template>
        </el-table-column>
      </el-table>
      <el-dialog v-model="dialogFormVisible" title="新增" width="500">
        <el-form :model="tableForm">
          <el-form-item label="排序" :label-width="80">
            <el-input v-model="tableForm.sort" autocomplete="off" />
          </el-form-item>
          <el-form-item label="演示端" :label-width="80">
            <el-input v-model="tableForm.demoDevice" autocomplete="off" />
          </el-form-item>
          <el-form-item label="地址" :label-width="80">
            <el-input v-model="tableForm.address" autocomplete="off" />
          </el-form-item>
          <el-form-item label="特殊说明" :label-width="80">
            <el-input v-model="tableForm.description" autocomplete="off" />
          </el-form-item>
          <el-form-item label="附加" :label-width="80">
            <el-upload
              multiple
              class="upload-demo"
              action=""
              :http-request="uploadFile"
              list-type="picture"
            >
              <el-button type="primary">上传文件</el-button>
            </el-upload>
          </el-form-item>
        </el-form>
        <template #footer>
          <div class="dialog-footer">
            <el-button @click="dialogFormVisible = false"> 取消 </el-button>
            <el-button type="primary" @click="dialogConfirm"> 确认 </el-button>
          </div>
        </template>
      </el-dialog>
    </div>
    <!-- Table end -->
  </div>
</template>
<script setup lang="ts">
import { Plus } from "@element-plus/icons-vue";
import { ref, onMounted, toRaw } from "vue";
import axios from "axios";
import { useRouter } from "vue-router";
import { Search } from "@element-plus/icons-vue";
import { Delete } from "@element-plus/icons-vue";
import { FolderChecked } from "@element-plus/icons-vue";
import { nextTick } from "vue";
import Sortable from "sortablejs";

const router = useRouter();
console.log(router.currentRoute.value.path); //当前路由路径
sessionStorage.setItem("path", router.currentRoute.value.path);

// 演示地址
// 拖动行排序
const changeRow = () => {
  const el = document.querySelector(".el-table__body-wrapper tbody");
  new Sortable(el, {
    animation: 150, // 动画
    // sort: true,
    ghostClass: "sortable-ghost",
    onEnd: (evt: any) => {
      console.log("oldIndex", evt.oldIndex); // 当前行的被拖拽前的顺序
      console.log("newIndex", evt.newIndex); // 当前行的被拖拽后的顺序
      const curRow = tableData.value.splice(evt.oldIndex, 1)[0];
      tableData.value.splice(evt.newIndex, 0, curRow);
      console.log("tableData.value新数据", tableData.value);
    },
  });
};

// 定义表格
const tableData = ref<any>([]);
// 定义弹窗表单
let tableForm = ref({
  sort: "",
  demoDevice: "",
  address: "",
  description: "",
  fileIds: <any>[],
  file: "",
});
// 默认对话框关闭状态
const dialogFormVisible = ref(false);
// 调用接口数据在表单显示
const port1 = async () => {
  await axios
    .post("http://192.168.1.214:5050/api/Project/DemoGetTable", {
      pageIndex: 1,
      pageSize: 100,
      projectId: "1",
    })
    .then((response) => {
      // 将找到的数据返回给表单显示
      tableData.value = response.data.data.list;
      console.log("tableData.value原数据", tableData.value);
    })
    .catch((error) => {
      console.error(error);
    });
};
// 挂载
onMounted(() => {
  port1();
  nextTick(() => {
    changeRow();
  });
});
// 搜索(通过name值查找)
const handleQueryName = () => {
  console.log("搜索");
};
// 新增
const handleAdd = async () => {
  // 打开新增对话框
  dialogFormVisible.value = true;
  // 设置空的绑定对象
  tableForm.value = {
    demoDevice: "",
    address: "",
    description: "",
    sort: "",
    fileIds: [],
    file: "",
  };
};
// 上传文件
const uploadFile = async (val: any) => {
  tableForm.value.file = val.file;
  // 数据交互
  let formdata = new FormData();
  formdata.append("File", tableForm.value.file);
  axios
    // 上传文件接口
    .post("http://192.168.1.214:5050/api/File/UploadFile", formdata, {
      headers: { "Content-Type": "multipart/form-data" },
    })
    .then((res) => {
      // 将文件id值传给tableForm的属性fileIds
      tableForm.value.fileIds.push(res.data.data.id);
      const newobj = Object.assign({ projectId: "1" }, toRaw(tableForm.value));
      axios
        // 添加演示地址接口
        .post("http://192.168.1.214:5050/api/Project/DemoAdd", newobj);
    });
};
// 删除
const handleRowDel = async (index: any) => {
  // 找到要删除的接口中对应的对象
  await axios.post("http://192.168.1.214:5050/api/Project/DemoDel", {
    // 获取到当前索引index下的id值,toRaw()方法获取原始对象
    id: toRaw(tableData.value[index]).id,
  });
  // 从index位置开始,删除一行即可
  tableData.value.splice(index, 1);
};
// 确认表单弹窗
const dialogConfirm = () => {
  dialogFormVisible.value = false;
  port1();
};
</script>

<style scoped lang="scss">
// 演示地址
.dem-add {
  width: 800px;
  margin: 20px 50px;
  background-color: rgba(255, 255, 255, 0.333);
  box-shadow: 0 8px 16px #0005;
  border-radius: 16px;
  overflow: hidden;
  // 标签
  .dem-title {
    display: flex;
    justify-content: space-between;
    align-items: center;
    background-color: rgba(207, 204, 204, 0.267);
    padding: 0 20px;
    p {
      float: left;
      width: 150px;
      color: #000;
    }
    // 搜索
    ::v-deep .el-input__wrapper {
      border-radius: 100px;
    }
    .query-input {
      width: 240px;
      height: 35px;
      margin: 10px auto;
      margin-left: 330px;
      background-color: transparent;
      transition: 0.2s;
    }
    ::v-deep .el-input__wrapper:hover {
      background-color: #fff8;
      box-shadow: 0 5px 40px #0002;
    }
    // 增加按钮
    .el-button {
      float: left;
      margin-top: 3px;
      margin-left: 10px;
    }
  }
  // 表格
  .bs-page-table {
    .el-table {
      width: 100%;
      border: 1px solid rgb(219, 219, 219);
      padding: 10px;
      .el-table-column {
        border-collapse: collapse;
        text-align: left;
      }
    }
  }
  // 分页
  .demo-pagination-block {
    padding: 9px 20px;
  }
}
</style>

#这个只是表面功夫,后端数据库中的数据排序一直都没变,所以想要真正改变排序,还需要后端写个接口。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1812945.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

我要成为算法高手-双指针篇

目录 什么是双指针?问题1&#xff1a;移动零问题2&#xff1a;复写零问题3&#xff1a;快乐数问题4&#xff1a;盛最多水的容器问题5&#xff1a;有效三角形个数问题6&#xff1a;查找总价格和为目标值的两个商品(两数之和)问题7&#xff1a;三数之和问题8&#xff1a;四数之和…

Nextjs 集成TinyMCE实现富文本编辑器

目录 一、导入依赖 二、动态导入 三、完整案例 四、参考文档 一、导入依赖 yarn add tinymce/tinymce-react二、动态导入 import dynamic from next/dynamic;const Editor dynamic(() > import(tinymce/tinymce-react).then(mod > mod.Editor),{ssr: false} ); 三…

力扣hot100:394. 字符串解码(递归/括号匹配,字符串之间相对顺序)

LeetCode&#xff1a;394. 字符串解码 本题容易想到用递归处理&#xff0c;在写递归时主要是需要明确自己的递归函数的定义。 不过我们也可以利用括号匹配的方式使用栈进行处理。 1、递归 定义递归函数string GetString(string & s,int & i); 表示处理处理整个numbe…

Django CreateView视图

CreateView是Django提供的一个基于类的视图&#xff0c;用于处理创建新对象的操作。它可以帮助你轻松地创建一个表单页面&#xff0c;用户可以通过这个页面创建新的对象。 1&#xff0c;添加视图 Test/app3/views.py from django.shortcuts import render# Create your views…

汇聚荣科技有限公司实力如何?

汇聚荣科技有限公司实力如何?在科技日新月异的今天&#xff0c;一个公司的实力往往体现在其技术创新能力、市场占有率、团队专业度、客户满意度以及财务健康状况等多个维度。针对“汇聚荣科技有限公司”这一话题&#xff0c;我们将从这五个方面进行深入探讨。 一、技术创新能力…

易舟云财务软件:数字化时代的财务管家

在数字化浪潮的推动下&#xff0c;财务软件成为了企业提升财务管理效率、实现数字化转型的关键工具。易舟云财务软件&#xff0c;正是这样一款深受企业喜爱的财务管理系统。本文将带你详细了解易舟云财务软件的特点、版本区别以及如何使用它来优化财务工作。 易舟云财务软件的特…

2024050901-重学 Java 设计模式《实战访问者模式》

重学 Java 设计模式&#xff1a;实战访问者模式「模拟家长与校长&#xff0c;对学生和老师的不同视角信息的访问场景」 一、前言 能力&#xff0c;是你前行的最大保障 年龄会不断的增长&#xff0c;但是什么才能让你不慌张。一定是能力&#xff0c;即使是在一个看似还很安稳…

格式化输出相关

格式化输出 使用print() %格式化 语法 “%[零个或一个或多个辅助指令]<格式化符号>”%(一个或多个变量、表达式、值) 格式化符号 %c 格式化为字符&#xff0c;整数或字符 %r 使用repr()函数格式化字符串 %s 使用str()函数格式化为字符串 %d 格式化为整数 %u…

Mybatis05-一对多和多对一处理

多对一和一对多 多对一 多对一的理解&#xff1a; 多个学生对应一个老师 如果对于学生这边&#xff0c;就是一个多对一的现象&#xff0c;即从学生这边关联一个老师&#xff01; 结果映射&#xff08;resultMap&#xff09;&#xff1a; association 一个复杂类型的关联&…

扩展学习|风险管理的文献综述汇总(持续更新向)

一、风险管理发展历程和趋势综述&#xff08;2007年发表&#xff09; 文献来源&#xff1a;[1]严复海,党星,颜文虎.风险管理发展历程和趋势综述[J].管理现代化, 2007(2):4.DOI:CNKI:SUN:GLXX.0.2007-02-009. 简介&#xff1a;该文以风险管理发展历程中的大事件为线索, 对风险管…

设计模式-享元模式(结构型)

享元模式 享元模式是一种结构型模式&#xff0c;它主要用于减少创建对象的数量&#xff0c;减少内存占用。通过重用现有对象的方式&#xff0c;如果未找到匹配对象则新建对象。线程池、数据库连接池、常量池等池化的思想就是享元模式的一种应用。 图解 角色 享元工厂&#xf…

Nginx05-负载均衡详解、LNMP+NFS、会话保持、负载均衡状态检查upstream-check、平滑升级

目录 写在前面Nginx05Nginx 负载均衡&#xff08;upstream模块&#xff09;概述常见选择负载均衡和反向代理的区别Nginx负载均衡的方式Nginx运行状况检查备份服务器Nginx upstream模块选项说明 实验1 负载均衡两台frontfront配置lb01配置测试流程梳理 实验2 LNMPNFS小实验NFS配…

网络安全课程开发

我们为卡巴斯基实验室开发了一个交钥匙教育门户网站&#xff0c;并为其开设了网络安全课程。在资源上&#xff0c;你可以熟悉课程的理论部分-观看视频或阅读插图文本版本&#xff0c;然后通过回答问题来验证你的知识。通过最终测试后&#xff0c;用户将获得证书。 对于这个项目…

hive 安装 嵌入模式 笔记

$ hive $ HIVE_HOME/bin/schematool -dbType derby –initSchema $ schematool -verbose -validate -dbType derby $HIVE_HOME/bin/hiveserver2 这个启动了先不要关闭&#xff0c;再打开一个终端进行下面的步骤 Beeline -u show databases 总结 报错1 WARN jdbc.HiveConnecti…

【ARM Cache 及 MMU 系列文章 6.4 -- ARMv8/v9 如何读取 Cache Tag 及分析其数据?】

请阅读【ARM Cache 及 MMU/MPU 系列文章专栏导读】 及【嵌入式开发学习必备专栏】 文章目录 Cache Tag 数据读取测试代码Cache Tag 数据读取 在处理器中,缓存是一种快速存储资源,用于减少访问主内存时的延迟。缓存通过存储主内存中经常访问的数据来实现这一点。为了有效地管…

图钉AI导航

1、图钉AI导航 https://www.tudingai.com/

应急物资管理系统|DW-S300构筑现代化战备保障的利器

行业背景 智慧应急物资管理系统&#xff08;智物资DW-S300&#xff09;是一套成熟系统&#xff0c;依托互3D技术、云计算、大数据、RFID技术、数据库技术、AI、视频分析技术对RFID智能仓库进行统一管理、分析的信息化、智能化、规范化的系统。 政府相关部门设立的应急物资库是…

Python pickle反序列化

基础知识 Pickle Pickle在Python中是一个用于序列化&#xff08;将对象转换为字节流&#xff09;和反序列化&#xff08;将字节流转换回对象&#xff09;的标准库模块。它主要用于将Python对象保存到文件或通过网络进行传输&#xff0c;使得数据可以跨会话和不同的Python程序共…

面试题:缓存穿透,缓存击穿,缓存雪崩

1 穿透: 两边都不存在&#xff08;皇帝的新装&#xff09; ——简介&#xff1a;缓存穿透指的是恶意用户或攻击者通过请求不存在于缓存和后端存储中的数据来使得所有请求都落到后端存储上&#xff0c;导致系统瘫痪。 ——详述&#xff1a;(缓存穿透是指查询一个一定不存在的数…

【lesson7】服务端业务处理模块实现

文章目录 业务处理实现思路业务处理类设计成员变量成员函数RunModuleupLoadlistShowdownLoadgetETagInfo 业务处理实现思路 云备份项目中 &#xff0c;业务处理模块是针对客户端的业务请求进行处理&#xff0c;并最终给与响应。而整个过程中包含以下要实现的功能&#xff1a; …