Python(Falsk) + React Golang(Gin) + Vue 全栈开发的最佳实践

本文主要是介绍Python(Falsk) + React Golang(Gin) + Vue 全栈开发的最佳实践,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        

        前面分别讲了 Python(Falsk) React Golang(Gin)Vue(Element),现在整体的给大家汇报一下,这个是简单搭建的demo,后面的添砖加瓦需要自己动手咯,有不明白的可以参考一下小编前面的文章,也许会给大家有答疑解惑的帮助

Python(Falsk):

https://blog.csdn.net/masterphp/article/details/136290855
https://blog.csdn.net/masterphp/article/details/138627802

React:

https://blog.csdn.net/masterphp/article/details/139242705

Golang(Gin):

https://blog.csdn.net/masterphp/article/details/129757434
https://blog.csdn.net/masterphp/article/details/130877001
https://blog.csdn.net/masterphp/article/details/131493155
https://blog.csdn.net/masterphp/article/details/131523360
https://blog.csdn.net/masterphp/article/details/132208407
https://blog.csdn.net/masterphp/article/details/132307220
https://blog.csdn.net/masterphp/article/details/132414796

Vscode的安装:

        首先讲一下Vscode的安装(用于React和Vue),本次完成项目的搭建,借助了一个工具:通意灵码,通意灵码:基于阿里云提供的一个服务,说的明白一点就是一个智能代码辅助工具,实际上用下来,个人觉得和Chatgpt平分秋色,各有各的优点与弊端,所以建议大家两个都去安装一下,适合自己的才是最好的

node14版本以上安装:

1.安装13版本
2.下载14版本zip(覆盖安装目录)
3.设置环境变量:NODE_SKIP_PLATFORM_CHECK :1
4.命令行使用 node -v 指令和npm -v ,检查当前 node 版本是否更新成功
5.设置全局模块存放路径和缓存文件夹(新建:node_global文件夹 + node_cache文件夹)
6.npm config set prefix "E:\node\node_global"    npm config set cache "E:\node\node_cache"
7.更换淘宝镜像(npm config set registry=https://registry.npm.taobao.org)
8.查看配置是否成功(npm config list)
9.设置环境变量: C:\Users\你的用户名\AppData\Roaming\npm 修改为 你的安装目录\node_global
10.新建环境变量(NODE_PATH :你的安装目录\node_global\node_modules)
11.新建环境变量(Path:%NODE_PATH%)

npm命令:

react-router-dom 安装命名(路由包):

npm install react-router-dom


antdesign安装命令(前端UI):

npm install antd --save
npm add antd@^4.24.2

使antdesign用babel-plugin-import插件可以实现按需加载:

npm install babel-plugin-import --save-dev


查看typescript版本:

npm view typescript version

CSS样式(5.0版本以下)

import  'antd/dist/antd.min.css'

CSS样式(5.0版本以上)

import 'antd/dist/antd.css'

cnpm安装

安装命令: npm install -g cnpm --registry=https://registry.npm.taobao.org 命令行下输入: cnpm -v 验证是否安装成功。


npm升级命令

npm install -g tar
npm uninstall fstream 


安装react:

1.npm install -g create-react-app(或者 npx create-react-app my-app)
2.create-react-app my-app(其中my-app是你的项目名称)
3.进入创建的项目目录:cd my-app
4.启动开发服务器:npm start


切换镜像:

npm config set registry= https://registry.npmjs.org/
npm config set registry=https://registry.npm.taobao.org

        Python使用的工具的PaCharm,使用这个工具的话需要激活码,所以大家懂的,有工具的,另外来说前期一个月的时间建议大家关闭代码提示,后期可以开启,主要是前期关闭可以加强关联记忆

        Golang使用的工具是Goland,其实使用Vscode也是非常好用的,看个人习惯,当然这个也是需要激活码的,所以嫌麻烦的同学可以直接上Vscode

Golang(Gin) + Vue:项目结构

GIN框架主入口:

package mainimport (//GIN框架引入"github.com/gin-gonic/gin"//自定义模块引入"project/common"user "project/controller"
)//初始化
func init()  {//数据库初始化common.Dbinit()
}func main()  {//GIN框架初始化r := gin.Default()//设置安全访问r.SetTrustedProxies([]string{"127.0.0.1"})//定义常量r.Static("/source", "static")//设置模版r.LoadHTMLGlob("template/*")/*******************登录页开始***********************/r.GET("/login", func(c *gin.Context) {c.HTML(200,"login.html", gin.H{"title": "登录"})})r.POST("/logindo", func(context *gin.Context) {username := context.PostForm("username")password := context.PostForm("password")//判断if(username == "12" && password == "34"){//todo 设置session//返回值context.JSON(200, gin.H{"code": 0,"message":"成功",})}else{context.JSON(200, gin.H{"code": 1,"message":"参数错误",})}})/*******************登录页结束***********************//*******************首页开始***********************/r.GET("/index", func(context *gin.Context) {context.HTML(200,"index.html",gin.H{"title": "首页"})})r.GET("/indexlist",user.Userlist)/*******************首页结束***********************//*******************用户开始***********************/r.GET("/user_add", func(context *gin.Context) {context.HTML(200,"user_add.html",gin.H{"title":"新增用户"})})r.POST("/user_add_do",user.User_add_do)//用户编辑r.GET("/user_edit", func(context *gin.Context) {id := context.Query("id")context.HTML(200,"user_edit.html",gin.H{"title":"编辑用户","id":id})})r.POST("/user_info",user.User_info)//操作编辑r.POST("/user_edit_do",user.User_edit_do)r.POST("/user_del", user.User_del)/*******************用户结束***********************//*******************文件上传开始***********************/r.POST("/imgupload",common.Imgupload)/*******************文件上传结束***********************/r.Run("localhost:8080")
}

数据库初始化:

package commonimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)//定义全局变量
var  DB *gorm.DB// 连接数据库的函数,返回一个 *sql.DB 对象以及一个 error 对象 (方法名记得大写,才可以被外部引用)。
func Dbinit(){dsn := "root:root@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"DB,_ = gorm.Open(mysql.Open(dsn), &gorm.Config{})fmt.Print("connect success")
}

公共方法:

package commonimport ("github.com/gin-gonic/gin"
)// 定义一个结构体来映射分页查询的数据
type Pagination struct {// 当前页码Page int `json:"page"`// 每页数量PageSize int `json:"pageSize"`// 总页数TotalPages int `json:"totalPages"`// 总记录数TotalCount int `json:"totalCount"`
}// 定义一个结构体来映射返回的数据
type Response struct {// 状态码Code int `json:"code"`// 数据Data interface{} `json:"data"`// 消息Msg string `json:"msg"`
}type Publicmodel struct {ID uint `json:"id" gorm:"primaryKey"`
}//文件上传
func Imgupload(context *gin.Context)  {// 单个文件(判断上传的文件是否为空)file, err := context.FormFile("file")if err != nil {context.JSON(500, gin.H{"message": err.Error(),})return}//文件上传路径dst := "./static/img/upload/" + file.Filename// 上传文件到指定的目录context.SaveUploadedFile(file, dst)//返回数据context.JSON(200, gin.H{"message": "上传成功","filename": file.Filename,"raw": dst,})
}

登录页面:

<style>@import url("/source/index.css");.el-input__inner{width: 80%!important;}#app{width: 100%;height: 100%;background: url(/source/img/loginbg.png) #F5F5F5 no-repeat;background-size: 70%;position: absolute}#content{ box-shadow: 22px 22px 0px #ebebeb;margin-top: 10%;z-index: 999;width: 475px;padding: 2rem;box-sizing: border-box;background-color: #fff;border-radius: 5px;position: relative;left: 60%;height: 30%}
</style><script src="/source/vue.js"></script>
<script src="/source/index.js"></script>
<script src="/source/axios.min.js"></script><div id="app"><div id="content"><el-form ref="form" :model="form" label-width="80px" ><el-form-item label="账号"><el-input type="text" v-model="form.username" autocomplete="off"  placeholder="请输入账号"></el-input></el-form-item><el-form-item label="密码"><el-input type="password" v-model="form.password" autocomplete="off" maxlength="10" placeholder="请输入密码"></el-input></el-form-item><el-form-item><el-button type="primary" @click="onSubmit(form)">立即创建</el-button></el-form-item></el-form></div>
</div><script>var Main = {data() {return {form: {username: '',password: '',},defaultProps: {children: 'children',label: 'label'}}},methods: {onSubmit(form) {//必须使用这个数组// let param = new URLSearchParams()let param = new FormData()//填充护数据param.append('username',this.form.username)param.append('password',this.form.password)//异步请求数据axios.post("/logindo",param).then((response)=>{if(response.data.code == 0){this.$message("提示:"+response.data.message);location.replace("/index", "_self");}else{this.$message("提示:"+response.data.message);}}).catch((error)=>{//错误捕获this.$message("请求错误,请重试");});},}}var Ctor = Vue.extend(Main)new Ctor().$mount('#app')
</script>

列表页面:

<style>@import url("/source/index.css");.el-header {background-color: #B3C0D1;color: #333;line-height: 60px;}.el-aside {color: #333;}
</style><script src="/source/vue.js"></script>
<script src="/source/index.js"></script>
<script src="/source/axios.min.js"></script><div id="app"><el-container style="height: 500px; border: 1px solid #eee"><el-aside width="200px" style="background-color: rgb(238, 241, 246)"><el-menu :default-openeds="['1', '3']"><el-submenu index="1"><template slot="title"><i class="el-icon-message"></i>导航一</template><el-menu-item-group><template slot="title">分组一</template><el-menu-item index="1-1">选项1</el-menu-item><el-menu-item index="1-2">选项2</el-menu-item></el-menu-item-group></el-submenu></el-menu></el-aside><el-container><!--右上角菜单开始--><el-header style="text-align: right; font-size: 12px"><el-dropdown><i class="el-icon-setting" style="margin-right: 15px"></i><el-dropdown-menu slot="dropdown"><el-dropdown-item>查看</el-dropdown-item><el-dropdown-item>新增</el-dropdown-item><el-dropdown-item>删除</el-dropdown-item><el-dropdown-item></el-dropdown-item></el-dropdown-menu></el-dropdown><span>王小虎</span>&nbsp;&nbsp;&nbsp;<el-button type="primary" @click="login_out()">退出</el-button></el-header><!--右上角菜单结束--><!--主体开始--><el-main><el-row><el-input v-model="input" placeholder="请输入内容" style="width: 80%"></el-input><el-button type="primary">搜索</el-button><el-button type="primary" @click="user_add()">新增</el-button></el-row><el-table :data="tableData"><el-table-column prop="id" label="ID" width="140"></el-table-column><el-table-column prop="username" label="姓名" width="120"></el-table-column><el-table-column prop="sex" label="性别"></el-table-column><el-table-column prop="age" label="年龄"></el-table-column><el-table-column label="操作"><template slot-scope="scope"><el-buttonsize="mini"@click="handleEdit(scope.$index, scope.row)">编辑</el-button><el-buttonsize="mini"type="danger"@click="handleDelete(scope.$index, scope.row)">删除</el-button></template></el-table-column></el-table><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="currentPage":page-sizes="[1, 2, 3, 4,5,6,7,8,9,10]":page-size="pageSize"layout="total, sizes, prev, pager, next, jumper":total="total"></el-pagination></el-main><!--主体结束--></el-container></el-container>
</div><script>var Main = {data() {return {tableData: [],currentPage: 1,pageSize: 2,total: 0,input: '',};},methods: {//定义刷新方法fetchData(page, size) {// 这里的API请求应该替换为实际的API地址和参数axios.get('/indexlist', {params: {page: page,size: size}}).then(response => {this.tableData = response.data.data.users;this.total = response.data.data.pagination.totalCount;}).catch(error => {console.error('Error fetching data: ', error);});},handleSizeChange(val) {this.pageSize = val;this.fetchData(this.currentPage, this.pageSize);},handleCurrentChange(val) {this.currentPage = val;this.fetchData(this.currentPage, this.pageSize);},handleEdit(index, row) {//编辑var id = row.idvar url = "/user_edit?id="+id;location.replace(url, "_self");},handleDelete(index, row) {//删除//异步请求axios({method: "post",url: "/user_del",data: {id:row.id},headers: { "Content-Type": "multipart/form-data" },}).then((response) => {if(response.data.code ==200){this.$message("提示:"+response.data.msg);//跳转this.fetchData(this.currentPage, this.pageSize);}else{this.$message("提示:"+response.data.msg);}});},//退出login_out(){this.$message("退出提示");},//用户新增user_add(){var url = "/user_add";location.replace(url, "_self");}},mounted(){//初始化加载this.fetchData(this.currentPage, this.pageSize);}}var Ctor = Vue.extend(Main)new Ctor().$mount('#app')
</script>

添加数据:

<style>@import url("/source/index.css");#content{width: 100%;height: 100%}
</style><script src="/source/vue.js"></script>
<script src="/source/index.js"></script>
<script src="/source/axios.min.js"></script><div id="app"><div id="content"><el-form ref="form" :model="form" label-width="80px"><el-form-item label="真实名称"><el-input v-model="form.username"  autocomplete="off"></el-input></el-form-item><el-form-item label="性别"><el-select v-model="form.sex" placeholder="请选择性别"><el-option label="男" value="男"></el-option><el-option label="女" value="女"></el-option></el-select></el-form-item><el-form-item label="年龄"><el-input type="number" v-model="form.age" autocomplete="off"></el-input></el-form-item><el-form-item><el-button type="primary" @click="onSubmit">立即创建</el-button><el-button>取消</el-button></el-form-item></el-form></div>
</div><script>var Main = {data() {return {form: {username: '',sex: '',age: '',}}},methods: {onSubmit(form) {//必须使用这个数组// let param = new URLSearchParams()let param = new FormData()//填充护数据param.append('username',this.form.username)param.append('sex',this.form.sex)param.append('age',this.form.age)//异步请求数据axios.post("/user_add_do",param).then((response)=>{if(response.data.code ==200){this.$message("提示:"+response.data.msg);//跳转setTimeout(function () {var url = "/index";location.replace(url, "_self");},1000);}else{this.$message("提示:"+response.data.msg);}}).catch((error)=>{//错误捕获this.$message("请求错误,请重试");});},}}var Ctor = Vue.extend(Main)new Ctor().$mount('#app')
</script>

编辑数据:

<style>@import url("/source/index.css");#content{width: 100%;height: 100%}.avatar-uploader .el-upload {border: 1px dashed #d9d9d9;border-radius: 6px;cursor: pointer;position: relative;overflow: hidden;}.avatar-uploader .el-upload:hover {border-color: #409EFF;}.avatar-uploader-icon {font-size: 28px;color: #8c939d;width: 178px;height: 178px;line-height: 178px;text-align: center;}.avatar {width: 178px;height: 178px;display: block;}
</style><script src="/source/vue.js"></script>
<script src="/source/index.js"></script>
<script src="/source/axios.min.js"></script><div id="app"><div id="content"><el-form ref="form" :model="form" label-width="80px"><el-form-item label="用户ID"><el-input type="number" v-model="form.id" autocomplete="off" disabled></el-input></el-form-item><el-form-item label="真实名称"><el-input v-model="form.username"  autocomplete="off"></el-input></el-form-item><el-form-item label="性别"><el-select v-model="form.sex" placeholder="请选择性别"><el-option label="男" value="男"></el-option><el-option label="女" value="女"></el-option></el-select></el-form-item><el-form-item label="年龄"><el-input type="number" v-model="form.age" autocomplete="off"></el-input></el-form-item><!--图片上传开始--><el-form-item label="头像" v-model="form.url"><el-uploadclass="avatar-uploader"action="/imgupload":show-file-list="false":on-success="handleAvatarSuccess":before-upload="beforeAvatarUpload"><img v-if="imageUrl" :src="imageUrl" class="avatar"><i v-else class="el-icon-plus avatar-uploader-icon"></i></el-upload></el-form-item><!--图片上传结束--><el-form-item><el-button type="primary" @click="onSubmit">确认修改</el-button></el-form-item></el-form></div>
</div><script>var Main = {data() {return {form: {id: '{{.id}}',username: '',sex: '',age: '',},imageUrl: ''}},methods: {fetchData() {// 这里的API请求应该替换为实际的API地址和参数axios({method: "post",url: "/user_info",data: {id:'{{.id}}'},headers: { "Content-Type": "multipart/form-data" },}).then((response) => {if(response.data.code ==200){//数据填充this.form.username = response.data.data.users[0].username;this.form.sex = response.data.data.users[0].sex;this.form.age = response.data.data.users[0].age;this.imageUrl = response.data.data.users[0].url;}else{this.$message("提示:"+response.data.msg);}});},onSubmit(form) {//填充数据let param = new FormData()//填充护数据param.append('id',this.form.id)param.append('username',this.form.username)param.append('sex',this.form.sex)param.append('age',this.form.age)param.append('url',this.imageUrl)//异步请求数据axios.post("/user_edit_do",param).then((response)=>{if(response.data.code ==200){this.$message("提示:"+response.data.msg);//跳转setTimeout(function () {var url = "/index";location.replace(url, "_self");},1000);}else{this.$message("提示:"+response.data.msg);}}).catch((error)=>{//错误捕获this.$message("请求错误,请重试");});},handleAvatarSuccess(res, file) {this.imageUrl = file.response.raw.replace("./static","http://127.0.0.1:8080/source")},beforeAvatarUpload(file) {const isJPG = file.type === 'image/jpeg';const isLt2M = file.size / 1024 / 1024 < 2;if (!isJPG) {this.$message.error('上传头像图片只能是 JPG 格式!');}if (!isLt2M) {this.$message.error('上传头像图片大小不能超过 2MB!');}return isJPG && isLt2M;},},mounted(){//初始化加载this.fetchData();}}var Ctor = Vue.extend(Main)new Ctor().$mount('#app')
</script>

Python(Falsk) + React 项目结构

Python(Flask)框架主入口:

from flask import Flask,Blueprint,json
from flask_cors import CORS
from xst.controller.user_controller import *
from xst.mapper.fileupload import *
import requests
from bs4 import BeautifulSoupapp = Flask(__name__)
#设置跨域
CORS(app)# 蓝图
admin = Blueprint('admin', __name__)# 登录操作
@admin.route('/logindo',methods=['POST'])
def logindo():# 获取数据(方式一)username = request.form['username']# 获取数据(方式二)# data = request.form.to_dict()# username = request.form['username']# 数据操作logindata = Userlogin(username)return json.dumps(logindata)# 用户列表
@admin.route('/userlist',methods=['POST','GET'])
def userlist():list = Userlist()return json.dumps(list)# 用户个数
@admin.route('/usernum',methods=['POST','GET'])
def usernum():num = Usercount()return json.dumps(num)# 用户新增
@admin.route("/useradd",methods=["POST"])
def useradd():# 接收数据username = request.form['username']sex = request.form['sex']age = request.form['age']url = request.form['url']# 请求方法result = Useradd(username,sex,age,url)return json.dumps(result)# 用户修改
@admin.route("/useredit",methods=["POST"])
def useredit():# 请求方法return json.dumps(Useredit())# 文件上传
@admin.route("/fileupload",methods=["POST"])
def fileupload():return json.dumps(Fileupload())# 蓝图注册
app.register_blueprint(admin,url_prefix='/admin')if __name__ == '__main__':app.run()

公共方法:

from flask import Flask
import mysql.connector# 数据库连接(设置参数)
mydb = mysql.connector.connect(host="localhost",user="root",passwd="root",database="test"
)
from flask import request
from werkzeug.utils import secure_filename
import os# 指定文件上传路径
UPLOAD_PATH = "/upload"
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}# 数据过滤器
def allowed_file(filename):return '.' in filename and \filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS# 文件上传方法
def Fileupload():# 判断文件是否存在if 'file' not in request.files:data = {"code": "300","msg": "修改成功","data": ""}return data# 获取文件file = request.files['file']if file.filename == '':data = {"code": "300","msg": "未选择文件","data": ""}return data# 这里可以加入文件类型的判断if file and allowed_file(file.filename):filename = secure_filename(file.filename)file.save(os.path.join(UPLOAD_PATH, filename))data = {"code": "200","msg": "上传成功","data": filename}return data

数据处理:

from xst.mapper.exts import mydb
from flask import request# 用户登录
def Userlogin(usernum):mycursor = mydb.cursor()# 获取数据量mycursor.execute("SELECT count(users.id) as num FROM users where username = '" + usernum + "'")num = mycursor.fetchone()[0]# 获取数据mycursor.execute("SELECT * FROM users where username = '" + usernum + "'")userinfo = mycursor.fetchall()# 判断if num >0:data = {"code": "200","msg": "成功","data": userinfo}else:data = {"code": "300","msg": "失败","data": ""}# 返回return data# 数据查询(获取数据量)
def Usercount():mycursor = mydb.cursor()mycursor.execute("SELECT count(users.id) as num FROM users")num = mycursor.fetchone()[0]# 数据组合data = {"code": "200","msg": "成功","data": num}# 返回return data# 数据查询(全部数据)
def Userlist():mycursor = mydb.cursor()mycursor.execute("SELECT * FROM users")userlist = mycursor.fetchall()# 数据组合data = {"code": "200","msg": "成功","data": userlist}# 返回return data# 数据查询(新增用户)
def Useradd(username,sex,age,url):mycursor = mydb.cursor()mycursor.execute("INSERT INTO users (username, sex, age, url) VALUES ('"+username+"', '"+sex+"', "+age+", '"+url+"');")mydb.commit()new_id = mycursor.lastrowid# 判断if new_id >0:data = {"code": "200","msg": "新增成功","data": new_id}else:data = {"code": "300","msg": "新增失败","data": ""}# 返回return data# 数据查询(修改用户)
def Useredit():# //接收数据id = request.form['id']username = request.form['username']sex = request.form['sex']age = request.form['age']url = request.form['url']# 数据操作mycursor = mydb.cursor()mycursor.execute("UPDATE users SET username = '"+username+"', sex = '"+sex+"', age = "+age+", url = '"+url+"' WHERE id = "+id)mydb.commit()# 判断if mycursor.rowcount > 0:data = {"code": "200","msg": "修改成功","data": ""}else:data = {"code": "300","msg": "修改失败","data": ""}# 返回return data

React主入口文件:

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import Route from './pages/route';
import reportWebVitals from './reportWebVitals';
// 新增路由组件
import { BrowserRouter } from "react-router-dom"const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<React.StrictMode><BrowserRouter><Route /></BrowserRouter></React.StrictMode>
);// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

主文件:

import React from "react";
import { useRoutes } from "react-router-dom"
import Userlist from "./userlist";
import Useradd from "./useradd";
import Useredit from "./useredit";
import Layout from "./layout";function Route(){const routes = useRoutes([{ path: "/userlist", element: <Userlist /> },{ path: "/useradd", element: <Useradd /> },{ path: "/useredit", element: <Useredit /> },{ path: "/*", element: <Layout /> },]);return (<div className="container"><div className="layout"><div style={{ width: '100%' }}>{routes}</div></div></div>);
}export default Route;

数据列表:

import React from 'react';
import { LikeOutlined, MessageOutlined, StarOutlined } from '@ant-design/icons';
import {List, Space } from 'antd';function Userlist(){// 设置数据const data = Array.from({ length: 23 }).map((_, i) => ({// 跳转地址href: 'https://ant.design',title: `序号: ${i}`,description:'描述',content:'内容',}));//列表渲染return (<ListitemLayout="vertical"size="large"pagination={{onChange: page => {console.log(page);},pageSize: 3,}}dataSource={data}renderItem={item => (<List.Itemkey={item.title}extra={<imgwidth={272}alt="logo"src="https://gw.alipayobjects.com/zos/rmsportal/mqaQswcyDLcXyDKnZfES.png"/>}><List.Item.Metatitle={<a href={item.href}>{item.title}</a>}description={item.description}/>{item.content}</List.Item>)}/>);
}export default Userlist;

新增数据:

import React from 'react';
// antdesign引入
import { Button, Form, Input,InputNumber  } from 'antd';
import { InboxOutlined } from '@ant-design/icons';
import { message, Upload,Select } from 'antd';
import "./layout.css"// 方法定义
function Useradd(){//常量定义const onFinish = (values) => {console.log('Success:', values);};const onFinishFailed = (errorInfo) => {console.log('Failed:', errorInfo);};//上传组件初始化const { Dragger } = Upload;const props = {name: 'file',multiple: true,action: 'https://www.mocky.io/v2/5cc8019d300000980a055e76',onChange(info) {const { status } = info.file;if (status !== 'uploading') {console.log(info.file, info.fileList);}if (status === 'done') {message.success(`${info.file.name} file uploaded successfully.`);} else if (status === 'error') {message.error(`${info.file.name} file upload failed.`);}},onDrop(e) {console.log('Dropped files', e.dataTransfer.files);},};//定义下拉组件const { Option } = Select;// 方法定义return (<Formname="basic"labelCol={{span: 8,}}wrapperCol={{span: 16,}}initialValues={{remember: true,}}onFinish={onFinish}onFinishFailed={onFinishFailed}autoComplete="off">{/* 用户名 */}<Form.Itemlabel="用户名"name="username"rules={[{required: true,message: 'Please input your 用户名!',},]}><Input /></Form.Item>{/* 性别 */}<Form.Itemlabel="性别"name="sex"rules={[{required: true,message: 'Please input your 性别!',},]}><Selectplaceholder="选择性别"allowClear><Option value="男">男</Option><Option value="女">女</Option></Select></Form.Item>{/* 年龄 */}<Form.Item name={['user', 'age']} label="年龄" rules={[{ type: 'number', min: 0, max: 99 }]}><InputNumber /></Form.Item>{/* 头像 */}<Form.Item label="头像"name="url"><Dragger {...props} maxCount={1}><p className="ant-upload-drag-icon"><InboxOutlined /></p><p className="ant-upload-text">点击上传</p><p className="ant-upload-hint">支持单次或批量上传</p></Dragger></Form.Item><Form.ItemwrapperCol={{offset: 8,span: 16,}}><Button type="primary" htmlType="submit">提交</Button></Form.Item></Form>);
}export default Useradd;

编辑数据:

import React from 'react';
// antdesign引入
import { Button, Form, Input,InputNumber  } from 'antd';
import { InboxOutlined } from '@ant-design/icons';
import { message, Upload,Select } from 'antd';
import "./layout.css"// 方法定义
function Useradd(){//常量定义const onFinish = (values) => {console.log('Success:', values);};const onFinishFailed = (errorInfo) => {console.log('Failed:', errorInfo);};//上传组件初始化const { Dragger } = Upload;const props = {name: 'file',multiple: true,action: 'http://127.0.0.1:500/fileupload',onChange(info) {const { status } = info.file;if (status !== 'uploading') {console.log(info.file, info.fileList);}if (status === 'done') {message.success(`${info.file.name} file uploaded successfully.`);} else if (status === 'error') {message.error(`${info.file.name} file upload failed.`);}},onDrop(e) {console.log('Dropped files', e.dataTransfer.files);},};//定义下拉组件const { Option } = Select;// 方法定义return (<Formname="basic"labelCol={{span: 8,}}wrapperCol={{span: 16,}}initialValues={{remember: true,}}onFinish={onFinish}onFinishFailed={onFinishFailed}autoComplete="off">{/* 用户名 */}<Form.Itemlabel="用户名"name="username"rules={[{required: true,message: 'Please input your 用户名!',},]}><Input /></Form.Item>{/* 性别 */}<Form.Itemlabel="性别"name="sex"rules={[{required: true,message: 'Please input your 性别!',},]}><Selectplaceholder="选择性别"allowClear><Option value="男">男</Option><Option value="女">女</Option></Select></Form.Item>{/* 年龄 */}<Form.Item name={['user', 'age']} label="年龄" rules={[{ type: 'number', min: 0, max: 99 }]}><InputNumber /></Form.Item>{/* 头像 */}<Form.Item label="头像"name="url"><Dragger {...props} maxCount={1}><p className="ant-upload-drag-icon"><InboxOutlined /></p><p className="ant-upload-text">点击上传</p><p className="ant-upload-hint">支持单次或批量上传</p></Dragger></Form.Item><Form.ItemwrapperCol={{offset: 8,span: 16,}}><Button type="primary" htmlType="submit">修改</Button></Form.Item></Form>);
}export default Useradd;

公共样式:

 .formbody{width: 40%;height: 25%;background: white;position: absolute;top: 30%;left: 50%;padding: 1.5rem !important;}.ant-col-8{flex: 0 0 20% !important}#root{padding: 1rem;}

至此讲解完成,主要讲解了登录、数据列表、数据新增、数据编辑,至于会话控制前面小编写的文章里面有,所以大家可以参考一下,还是那句话,脑袋会了手不一定会了,所以多练练习。

这篇关于Python(Falsk) + React Golang(Gin) + Vue 全栈开发的最佳实践的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1092377

相关文章

HTML5中的Microdata与历史记录管理详解

《HTML5中的Microdata与历史记录管理详解》Microdata作为HTML5新增的一个特性,它允许开发者在HTML文档中添加更多的语义信息,以便于搜索引擎和浏览器更好地理解页面内容,本文将探... 目录html5中的Mijscrodata与历史记录管理背景简介html5中的Microdata使用M

html5的响应式布局的方法示例详解

《html5的响应式布局的方法示例详解》:本文主要介绍了HTML5中使用媒体查询和Flexbox进行响应式布局的方法,简要介绍了CSSGrid布局的基础知识和如何实现自动换行的网格布局,详细内容请阅读本文,希望能对你有所帮助... 一 使用媒体查询响应式布局        使用的参数@media这是常用的

HTML5表格语法格式详解

《HTML5表格语法格式详解》在HTML语法中,表格主要通过table、tr和td3个标签构成,本文通过实例代码讲解HTML5表格语法格式,感兴趣的朋友一起看看吧... 目录一、表格1.表格语法格式2.表格属性 3.例子二、不规则表格1.跨行2.跨列3.例子一、表格在html语法中,表格主要通过< tab

Python实现特殊字符判断并去掉非字母和数字的特殊字符

《Python实现特殊字符判断并去掉非字母和数字的特殊字符》在Python中,可以通过多种方法来判断字符串中是否包含非字母、数字的特殊字符,并将这些特殊字符去掉,本文为大家整理了一些常用的,希望对大家... 目录1. 使用正则表达式判断字符串中是否包含特殊字符去掉字符串中的特殊字符2. 使用 str.isa

python中各种常见文件的读写操作与类型转换详细指南

《python中各种常见文件的读写操作与类型转换详细指南》这篇文章主要为大家详细介绍了python中各种常见文件(txt,xls,csv,sql,二进制文件)的读写操作与类型转换,感兴趣的小伙伴可以跟... 目录1.文件txt读写标准用法1.1写入文件1.2读取文件2. 二进制文件读取3. 大文件读取3.1

使用Python实现一个优雅的异步定时器

《使用Python实现一个优雅的异步定时器》在Python中实现定时器功能是一个常见需求,尤其是在需要周期性执行任务的场景下,本文给大家介绍了基于asyncio和threading模块,可扩展的异步定... 目录需求背景代码1. 单例事件循环的实现2. 事件循环的运行与关闭3. 定时器核心逻辑4. 启动与停

基于Python实现读取嵌套压缩包下文件的方法

《基于Python实现读取嵌套压缩包下文件的方法》工作中遇到的问题,需要用Python实现嵌套压缩包下文件读取,本文给大家介绍了详细的解决方法,并有相关的代码示例供大家参考,需要的朋友可以参考下... 目录思路完整代码代码优化思路打开外层zip压缩包并遍历文件:使用with zipfile.ZipFil

Python处理函数调用超时的四种方法

《Python处理函数调用超时的四种方法》在实际开发过程中,我们可能会遇到一些场景,需要对函数的执行时间进行限制,例如,当一个函数执行时间过长时,可能会导致程序卡顿、资源占用过高,因此,在某些情况下,... 目录前言func-timeout1. 安装 func-timeout2. 基本用法自定义进程subp

Python实现word文档内容智能提取以及合成

《Python实现word文档内容智能提取以及合成》这篇文章主要为大家详细介绍了如何使用Python实现从10个左右的docx文档中抽取内容,再调整语言风格后生成新的文档,感兴趣的小伙伴可以了解一下... 目录核心思路技术路径实现步骤阶段一:准备工作阶段二:内容提取 (python 脚本)阶段三:语言风格调

Python结合PyWebView库打造跨平台桌面应用

《Python结合PyWebView库打造跨平台桌面应用》随着Web技术的发展,将HTML/CSS/JavaScript与Python结合构建桌面应用成为可能,本文将系统讲解如何使用PyWebView... 目录一、技术原理与优势分析1.1 架构原理1.2 核心优势二、开发环境搭建2.1 安装依赖2.2 验