首页 后端开发 Golang 如何使用Go语言和React构建可拖拽的列表

如何使用Go语言和React构建可拖拽的列表

Jun 17, 2023 pm 01:12 PM
react go语言 可拖拽列表

在现代Web应用程序中,拖拽功能已经成为标配之一,这是因为它能给用户更好的交互体验。在这篇文章中,我们将介绍如何使用Go语言和React构建可拖拽的列表,让你的Web应用程序更加易于使用和有趣。

第一步:搭建后端服务

首先,我们需要搭建一个后端服务,用来管理列表的数据。我们将使用Go语言创建一个简单的REST API。为了简化我们的代码,我们将同时使用Gin框架和GORM库。

首先,我们需要创建一个名为“items”的表,以存储我们的列表项。

CREATE TABLE items (
    id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(255) NOT NULL,
    position INT NOT NULL,
    PRIMARY KEY (id)
);
登录后复制

接下来,我们创建一个Golang文件,并在其中添加以下代码:

package main

import (
    "github.com/gin-gonic/gin"
    "github.com/jinzhu/gorm"
    _ "github.com/jinzhu/gorm/dialects/mysql"
)

type Item struct {
    ID       int    `gorm:"primary_key" json:"id"`
    Name     string `gorm:"not null" json:"name"`
    Position int    `gorm:"not null" json:"position"`
}

func main() {
    // 初始化Gin框架
    r := gin.Default()

    // 连接MySQL数据库
    db, err := gorm.Open("mysql", "{username}:{password}@/{database_name}?charset=utf8&parseTime=True&loc=Local")
    if err != nil {
        panic("无法连接到数据库")
    }
    defer db.Close()

    // 自动迁移schema
    db.AutoMigrate(&Item{})

    // 添加CORS中间件
    r.Use(corsMiddleware())

    // 定义API路由
    api := r.Group("/api")
    {
        api.GET("/items", listItems)
        api.PUT("/items/:id", updateItem)
    }

    // 启动服务
    r.Run(":8080")
}

// 列出所有项
func listItems(c *gin.Context) {
    db := c.MustGet("db").(*gorm.DB)

    var items []Item
    db.Find(&items)

    c.JSON(200, items)
}

// 更新单个项目
func updateItem(c *gin.Context) {
    db := c.MustGet("db").(*gorm.DB)

    // 从URL参数获得项目的ID
    id := c.Param("id")

    // 从请求体得到项目的其他项(名称和位置)
    var input Item
    if err := c.BindJSON(&input); err != nil {
        c.JSON(400, gin.H{"error": err.Error()})
        return
    }

    // 更新数据库
    var item Item
    if db.First(&item, id).RecordNotFound() {
        c.JSON(404, gin.H{"error": "项目未找到"})
        return
    }

    item.Name = input.Name
    item.Position = input.Position

    if err := db.Save(&item).Error; err != nil {
        c.JSON(400, gin.H{"error": "更新项目失败"})
        return
    }

    c.JSON(200, item)
}

// 添加CORS中间件
func corsMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
        c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, OPTIONS")
        c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type")
        c.Writer.Header().Set("Access-Control-Max-Age", "86400")
        if c.Request.Method == "OPTIONS" {
            c.AbortWithStatus(200)
            return
        }
        c.Next()
    }
}
登录后复制

在这段代码中,我们首先创建了一个名为“items”的表,用来存储列表项。然后,我们创建了一个名为“Item”的结构体,并在其中定义了其字段。接着,我们创建了一个名为“listItems”的函数,用来从数据库中获取所有项目,并将它们以JSON形式返回。我们还创建了一个名为“updateItem”的函数,用来更新单个项目。

我们在这个Golang文件中创建了一个名为“api”的路由组,定义了两个路由:GET /items 和 PUT /items/:id。GET路由用于获取所有项目,PUT路由用于更新单个项目。

我们还添加了一个名为“corsMiddleware”的中间件,用于处理CORS问题。CORS允许一个域中的代码向另一个域中的API发起请求,这在开发Web应用程序时非常常见。

第二步:构建React前端

接下来,我们需要创建React前端。我们将使用React和React-DnD库来实现拖拽功能。我们还将使用Axios库,用来从后端服务器获取数据。

首先,我们需要创建一个名为“ItemList”的文件夹,并将以下代码保存到名为“ItemList.jsx”的文件中:

import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';

export default function ItemList() {
    const [items, setItems] = useState([]);

    useEffect(() => {
        axios.get('http://localhost:8080/api/items').then((response) => {
            setItems(response.data);
        });
    }, []);

    function onDragEnd(result) {
        const { destination, source, draggableId } = result;
        if (!destination) {
            return;
        }
        if (
            destination.droppableId === source.droppableId &&
            destination.index === source.index
        ) {
            return;
        }

        const item = items.find((i) => i.id === parseInt(draggableId));
        const newItems = [...items];
        newItems.splice(source.index, 1);
        newItems.splice(destination.index, 0, item);

        axios
            .put(`http://localhost:8080/api/items/${draggableId}`, {
                name: item.name,
                position: destination.index,
            })
            .then(() => {
                setItems(newItems);
            });
    }

    return (
        <DragDropContext onDragEnd={onDragEnd}>
            <Droppable droppableId="itemList">
                {(provided) => (
                    <ul
                        {...provided.droppableProps}
                        ref={provided.innerRef}
                        className="item-list"
                    >
                        {items.map((item, index) => {
                            return (
                                <Draggable
                                    key={item.id}
                                    draggableId={item.id.toString()}
                                    index={index}
                                >
                                    {(provided) => (
                                        <li
                                            {...provided.draggableProps}
                                            {...provided.dragHandleProps}
                                            ref={provided.innerRef}
                                            className="item"
                                        >
                                            {item.name}
                                        </li>
                                    )}
                                </Draggable>
                            );
                        })}
                        {provided.placeholder}
                    </ul>
                )}
            </Droppable>
        </DragDropContext>
    );
}
登录后复制

在这个React组件中,我们首先使用useState和useEffect来获取列表项的数据。然后,我们创建了一个名为“onDragEnd”的函数,用来处理拖拽事件并更新数据。我们还使用React-DnD库创建了一个可拖拽的列表。在这个“ItemList”组件中,我们渲染了一个包含所有列表项的

    元素,并使用组件将它们设置为可拖拽。我们还使用组件来包装整个列表,使其可接受拖拽操作。

    现在,我们需要在我们的应用程序中使用这个组件。在我们的React应用程序中,我们创建了一个名为“App”的组件,并将添加到它的JSX中。接下来,我们添加以下代码到一个名为“index.js”的文件中,用来渲染我们的React应用程序:

    import React from 'react';
    import ReactDOM from 'react-dom';
    import App from './App';
    
    ReactDOM.render(<App />, document.getElementById('root'));
    登录后复制

    第三步:运行应用程序

    现在,我们已经完成了应用程序的开发。我们需要启动后端服务和前端React应用程序以查看它们运行。首先,我们需要双开终端窗口,在其中一个窗口中切换到我们的Go应用程序目录,运行以下命令:

    go run main.go
    登录后复制

    然后,在另一个终端窗口中切换到我们的React应用程序目录,运行以下命令:

    npm start
    登录后复制

    现在,我们可以在浏览器中访问http://localhost:3000/,就可以看到我们的可拖拽列表了。现在你可以玩耍一下,看看你是否可以自如地拖动列表项,而且它们在后端服务中也会相应地更新。

    结论

    在这篇文章中,我们使用Go语言和React构建了一个可拖动列表,通过Gin和React-DnD库,我们实现了拖拽列表项的功能,并通过Axios库从后端服务器获取数据。这个示例项目可以作为你日常工作开发中的一个参考。

    以上是如何使用Go语言和React构建可拖拽的列表的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

vue.js vs.反应:特定于项目的考虑因素 vue.js vs.反应:特定于项目的考虑因素 Apr 09, 2025 am 12:01 AM

Vue.js适合中小型项目和快速迭代,React适用于大型复杂应用。1)Vue.js易于上手,适用于团队经验不足或项目规模较小的情况。2)React的生态系统更丰富,适合有高性能需求和复杂功能需求的项目。

React在HTML中的作用:增强用户体验 React在HTML中的作用:增强用户体验 Apr 09, 2025 am 12:11 AM

React通过JSX与HTML结合,提升用户体验。1)JSX嵌入HTML,使开发更直观。2)虚拟DOM机制优化性能,减少DOM操作。3)组件化管理UI,提高可维护性。4)状态管理和事件处理增强交互性。

Go语言中用于浮点数运算的库有哪些? Go语言中用于浮点数运算的库有哪些? Apr 02, 2025 pm 02:06 PM

Go语言中用于浮点数运算的库介绍在Go语言(也称为Golang)中,进行浮点数的加减乘除运算时,如何确保精度是�...

Go的爬虫Colly中Queue线程的问题是什么? Go的爬虫Colly中Queue线程的问题是什么? Apr 02, 2025 pm 02:09 PM

Go爬虫Colly中的Queue线程问题探讨在使用Go语言的Colly爬虫库时,开发者常常会遇到关于线程和请求队列的问题。�...

在 Go 语言中,为什么使用 Println 和 string() 函数打印字符串会出现不同的效果? 在 Go 语言中,为什么使用 Println 和 string() 函数打印字符串会出现不同的效果? Apr 02, 2025 pm 02:03 PM

Go语言中字符串打印的区别:使用Println与string()函数的效果差异在Go...

在Go语言中使用Redis Stream实现消息队列时,如何解决user_id类型转换问题? 在Go语言中使用Redis Stream实现消息队列时,如何解决user_id类型转换问题? Apr 02, 2025 pm 04:54 PM

Go语言中使用RedisStream实现消息队列时类型转换问题在使用Go语言与Redis...

GoLand中自定义结构体标签不显示怎么办? GoLand中自定义结构体标签不显示怎么办? Apr 02, 2025 pm 05:09 PM

GoLand中自定义结构体标签不显示怎么办?在使用GoLand进行Go语言开发时,很多开发者会遇到自定义结构体标签在�...

Go语言中哪些库是由大公司开发或知名的开源项目提供的? Go语言中哪些库是由大公司开发或知名的开源项目提供的? Apr 02, 2025 pm 04:12 PM

Go语言中哪些库是大公司开发或知名开源项目?在使用Go语言进行编程时,开发者常常会遇到一些常见的需求,�...

See all articles