个人blog系统 前后端分离 前端js后端go

发布于:2025-03-19 ⋅ 阅读:(14) ⋅ 点赞:(0)

系统设计:

1.使用语言:前端使用vue,并使用axios向后端发送数据。后端使用的是go的gin框架,并使用grom连接数据库实现数据存储读取。

2.设计结构:

最终展示:仅展示添加模块,其他模块基本相似

 前端部分

基础的页面设计部分使用的是flex布局,这里就不过多的讲解了。

由于vue是模块化的,所以这个页面可以分为三大模块

1.就是app.vue这个是最主要的,我们的页面是通过它来显示的

2.就是左侧的导航栏,它对应四个模块,根据选择模块不同来显示不同的页面

3.就是右侧的交互部分,四个交互页面对应四个导航栏的选项

运行端口

运行端口有默认的端口,如果需要自定义端口。我们需要在项目文件中找到vue.config.js文件。然后在里面设置:

原来的文件内容:
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
 
})


修改后
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  devServer:{//主要添加这个
    port: 3000,
    open: true,
  }
})

port指定端口,open指定程序运行的时候是否自动打开浏览器true为打开

 组件

想要使用组件就需要提前加载组件,也就是导入它(import ...)

加载之后才能挂载(router-view)

我们首先要明确的目标是:1 加载 2对应的组件   2 加载 3对应的组件

我们一步一步来看

大致的文件结构如下图所示,仅做展示,为了方便了解结构

app.vue:

<template>
<div class="father">
  <div class="one">
    <h1>blog control center</h1>
  </div>
  <div>
    <index />
  </div>
</div>
</template>

<script>
import index from "./views/index.vue"


export default {
  name: "App",
  components: {
    index,
  }
}
</script>

<style>

.father {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}
.one{
  width: 1380px;
  height: 100px;
  background: #8e96f1;
  text-align: center;
  display: flex;
  justify-content: center;
}

</style>

 App.vue这是整个项目的根组件。其他所有的组件都是基于这个组件展开的

我们主要在这个组件内做了:

  1. 加载 index组件
  2. 制作了HTML的头部区域,也就是显示blog control center 的部分
  3. 规定了index的显示区域(为头部区域下方
  4. 给body设置了一个flex布局,让网页内容居中显示

加载组件就是在组件的script部分通过import导入,加载分为全局加载组件内加载

在上面的代码中我们使用的是组件内加载,它的特点是,在其组件内加载的组件只能在此组件内使用。而全局加载的特点是只要我们使用全局加载,那么在这个项目内所有组件都可以使用我们加载的组件。

全局加载步骤:首先在main.js里面加载需要用的组件。

import xxx from "相对路径"   xxx就相当于我们给这个组件起的别名

然后我们会看到一个语句:const app = createApp(APP)

然后通过 app.conponent("组件名",组件名)

注意:如果没有找到const app = createApp(APP)那就是被集成为了createApp(APP).use(router).mount('#app')放在最下方。这时候我们需要把它拆开

我们来看一个简单的例子:

import index from  "./views/index.vue"

const app =createApp(App)

app.component("index",index)

app.use(router).mount('#app')

这就是全局导入的基本步骤了。在这里导入之后就不需要在组件内搞import和components了。直接<index />就可以使用了

这里我们就讲解完了,接下来我们来看index的设置

index:



<template>
<div class="body">
  <div >
    <div class="son" style="background-color: #42b983">
      <router-link to="/add" ><h1>添加博文</h1></router-link>
    </div>
    <div class="son" style="background-color: gold">
      <router-link to="/change"><h1>修改博文</h1></router-link>
    </div>
    <div class="son" style="background-color: pink">
      <router-link to="/discover"> <h1>查询博文</h1></router-link>
    </div>
    <div class="son" style="background-color: coral">
      <router-link to="/del"> <h1>删除博文</h1></router-link>
    </div>
  </div>
  <div style="width: 1200px;height: 1120px;">
<router-view></router-view>
  </div>
</div>
</template>

<script>

export default {
  setup() {
    return{
    }
  },

}
</script>

<style scoped>

.son{
  width: 180px;
  height: 280px;
  display: flex;
  justify-content: center;
  align-items: center;
}
.body{
  display: flex;
  flex-direction: row;
}
</style>

这里主要要理解的是router-viewrouter-link 

router-view是组件要挂载到哪里的入口,也就是说我的router-view放在div里面,我的子组件展示的时候就只能在这个div里面展示。它起到一个占位符的作用,需要与router-link结合使用

router-link就相当于一个连接,这个连接里面设置的路径是我们在router目录里面提前设置好的。针对于这个项目我们来看一下router里面index.js的设置

import { createRouter, createWebHashHistory } from 'vue-router'
import index from "../views/index.vue"
import add from "../views/add.vue"
import change from "../views/change.vue"
import discover from "../views/discover.vue"
import del from "../views/del.vue"


const routes = [
  {
    path: '/index',
    component: index,
  }
  ,{
  path: '/add',
    component: add,

  }
  ,{
  path: '/change',
    component: change,
  }
  ,{
  path: '/discover',
    component: discover,
  }
  ,{
  path: '/del',
    component: del,
  }
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router

路径的设置主要是创建一个数组,数组存储对象,对象存储路径信息(path和component)path是我们设置的路径,component是我们导入的组件。由于它是一个.js文件不知道哪些组件被注册为全局组件。所以需要重新加载一次 

最后我们再创建一个router,吧createRouter([])赋值给它。在这个函数里面有两个参数。这里暂且略过,因为博主也没有很理解这个。就暂且按照博主的写法来吧(嘻嘻)

最后的export default router这个语句的作用是导出一个router对象。这样问再main里面才可以使用(app.use(router))(注:使用之前需要import导入index.js所在的相对地址哦)

到此,router-view和router-link我们也大致的明白是怎么回事了,简单来说就是router-link连接显示的组件会显示到router-view里面。

然后我们再来看四个不同模块文件

add.vue:

<script>
import {ref} from "vue";
import axios from "axios"
export default{
  name:"add",
  setup(props,context) {
    let name = ref("")
    let text = ref("")
    let rese =ref("")
    function give(e) {
      e.preventDefault()
      axios.post("http://localhost:8081/Add",{
        name: name.value,
        text: text.value
      }).then(res => {
        console.log(res)
        alert(res.data.Error)
        rese.value = res.data.Error
      })
    }
    return{
      give,
      name,
      text,
    }
  }

}
</script>

<template>
 <div class="rit">
   <form method="post"  @submit="give" >
   <table>
     <tr class="a"><td> 请输入博文名称: <input name="name" v-model="name" type="text" style="width: 500px"><input  type="submit" value="提交" class="submit-button"></td></tr>
     <tr class="b"><td><textarea name="text" v-model="text" /></td></tr>
   </table>
   </form>
 </div>
</template>

<style scoped>
div{
  display: flex;
  align-items: center;
  justify-content: center;
}
.rit{
  width: 1200px;
  height: 1120px;
  background: #42b882;
}
.a{
width:1200px;
  height: 100px;
}
.b{
  width:1200px;
  height: 1025px;
}
textarea{
  width:1100px;
  height:1000px;
  overflow:auto;
}
</style>
全局css样式

 这里我们不怎么酱它的css样式,只简单了解一下:通常来说,组件之间的css样式不会互相影响,也就是说我在哪个组件设置的样式就只能用在哪个组件内。
如果有一个样式会被运用到很多组件内,我们就可以设置全局css样式

全局css样式

设置全局css样式我们需要单独写一个css文件,通常这个文件我们会存放在src/assets目录下。

导入全局组件同样需要在main.js里面导入(import "css样式路径(相对路径)")

这样就可以直接在组件内使用这个文件内的样式了。

axios 传递数据

这里我们传递数据使用到了axios作为传递的工具。

我们首先导入这个axios,同样的。既然是导入就会有全局导入和组件内导入

组件内导入很简单,我们不过多赘述

我们主要来讲一下全局导入

在main.js我们首先 import axios from "axios"导入

然后

axios.defaults.baseURL = 'http://localhost:8081'; // 设置默认的 baseURL

这里设置的作用是在组件内使用的时候就不需要写完整的路径了,只需要补出后面剩余路径即可:.post("http://localhost:8081/Add" 就可以写为.post("/Add"

这样就会方便很多。

然后app.config.globalProperties.$axios = axios; 这一句的作用类似于起别名。我们在组件内导入的时候使用axios直接使用就可以了。但是全局导入就需要this.$axios了   $axios也可以改成别的名字,这个看自己需要。$也可以不写,但是我们通常会写上哦

 如果使用全局导入,我们刚才的代码就需要改为:

 setup(props,context) {
    let name = ref("")
    let text = ref("")
    let rese =ref("")
    function give(e) {
      e.preventDefault()
      this.$axios.post("/Add",{
        name: name.value,
        text: text.value
      }).then(res => {
        console.log(res)
        alert(res.data.Error)
        rese.value = res.data.Error
      })
    }

this.$axios

这里要着重声明的是,在vue3的里面这个方法就不是很适用了。因为setup没有自己的this

我们需要

import {getCurrentInstance} from "vue";事先导入这个

const { proxy } = getCurrentInstance(); // 然后再在setup里面创建这个常量。通过

proxy.$axios进行使用,这里的差异要注意

我们使用this.$axios.post.("url",{json键值对数据})向后端发送请求。然后再.then(res=>{接收回应})接收后端返回的回应(一般都是res.data里面有回应的数据)。然后再.catch捕获错误信息,这个在本系统内并没有使用(不会)

ref变量

这个是vue3里面新出的一个,通过它来创建响应式变量,用于绑定页面内元素。实现动态的变化。如果要在js所属的代码部分访问它的值是不能直接用变量名的,而是需要使用  变量名.value  获取变量的值。

v-model绑定

它的主要作用是把一个变量绑定到某个元素上,这个变量要是响应式变量。它有一个语法糖,就是先读取后渲染。把它综合到了v-model里面。

change.vue:

<script>
import { ref } from "vue";

export default {
  name: "add",
  setup() {
    let change_text = ref("");
    let Blog_body = ref("");
    let Blog_title = ref("");

    function change_submit(e) {
      e.preventDefault();
      console.log("change_text:", change_text.value); // 检查值
      this.$axios.post("/Change",{
        "Title": change_text.value
      }).then((response) => {
        console.log(response);
        Blog_body.value = response.data.Blog_body;
        Blog_title.value = response.data.Blog_title;
        alert("i get the blog");
      });
    }
    function change_out(e){
      e.preventDefault()
      alert("数据发送回后端",Blog_title,Blog_body)
      this.$axios.post("/Changeend", {
        BlogText: Blog_body.value,
        BlogName:Blog_title.value,
      }).then((response) => {
        alert(response.data.return);
      })
    }

    return {
      change_submit,
      change_text,
      Blog_title,
      Blog_body,
      change_out,
    };
  },
};
</script>

<template>
  <div class="rit">
    <form method="post" @submit="change_submit">
      <table>
        <tr class="a">
          <td>
            请输入要修改的博文的名称:<input type="text" style="width: 500px" v-model="change_text" />
            <input type="submit" value="提交" class="submit-button" />
          </td>
        </tr>

      </table>
    </form>
    <form @submit="change_out" id="f2">
      <table>
        <tr class="a">
          <td>
            blog_name:<input type="text" style="width: 500px" v-model="Blog_title" />
            <input type="submit" value="确认提交" class="submit-button">
          </td>
        </tr>
        <tr class="b">
          <td>
            <textarea v-model="Blog_body"></textarea>
          </td>
        </tr>
      </table>
    </form>
  </div>
</template>

<style scoped>
div{
  display: flex;
  align-items: center;
  justify-content: center;
}
.rit{
  width: 1200px;
  height: 1120px;
  background: #fdd600;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

.a{
  width:1200px;
  height: 50px;
  text-align: center;
}
.b{
  width:1200px;
  height: 1025px;
}
textarea{
  width:1100px;
  height:1000px;
  overflow:auto;
}
</style>

这个里面就没有什么特别新的内容了,我们简单理解一下设计概念即可。在change模块中。主要步骤如下

  1. 前端输入blog的name
  2. 发送给后端,后端返还blog的name和内容   这是第一次前后端交流
  3. 用户修改,再次返回给后端
  4. 后端接收,修改数据库中的数据(是修改不是新建一个新的数据)这是第二次前后端交流

这里着重讲一下的是使用了两个路由,一个路由用于第一次前后端交流,另一个路由用于第二次前后端交流。

其他的部分都是之前讲过的了。就不过多赘述了

后面的del.vue和discover.vue模块都是重复的内容,我们只把代码贴出来,剩下的就略过了

del.vue

<script>
import {ref} from "vue";


export default{
  name:"add",
  setup() {
    let blogs_name = ref("")
    function del_blog(e){
      e.preventDefault()
      console.log("函数被触发")
      this.$axios.post("/Delete",
          {"blog_name":blogs_name.value}).then(res=>{
        alert("blog 删除"+res.data.return)
        console.log(res)
      })

    }
    return {
      blogs_name,
      del_blog,
    }
  }

}
</script>

<template>
  <div class="rit">
    <form method="post" @submit="del_blog" >
      <table>
        <tr class="a"><td> 请输入要删除的博文名称: <input type="text" style="width: 500px" v-model="blogs_name"><input type="submit" value="提交" class="submit-button" ></td></tr>
      </table>
    </form>
  </div>
</template>

<style scoped>
div{
  display: flex;
  align-items: center;
  justify-content: center;
}
.rit{
  width: 1200px;
  height: 1120px;
  background: #fd7e50;
}
.a{
  width:1200px;
  height: 100px;
}

textarea{
  width:1100px;
  height:1000px;
  overflow:auto;
}
</style>

discover.vue 

<script>
import {ref} from "vue";


export default{
  name:"add",
  setup() {
    let change_text = ref("");
    let Blog_body = ref("");
    let Blog_title = ref("");

    function change_submit(e) {
      e.preventDefault();
      console.log("change_text:", change_text.value); // 检查值
      this.$axios.post("/Discover",{
        "Title": change_text.value
      }).then((response) => {
        console.log(response);
        Blog_body.value = response.data.Blog_body;
        alert("i get the blog");
      });
    }

    return {
      Blog_body,
      Blog_title,
      change_text,
      change_submit,
    }
  }

}
</script>

<template>
  <div class="rit">
    <form method="post" @submit="change_submit">
      <table>
        <tr class="a"><td> 请输入要查询的博文名称: <input type="text" style="width: 500px" v-model="change_text"><input type="submit" value="提交"  class="submit-button"> </td></tr>
        <tr class="b"><td><textarea v-model="Blog_body"/></td></tr>
      </table>
    </form>
  </div>
</template>

<style scoped>
div{
  display: flex;
  align-items: center;
  justify-content: center;
}
.rit{
  width: 1200px;
  height: 1120px;
  background: #fdbfca;
}
.a{
  width:1200px;
  height: 100px;
}
.b{
  width:1200px;
  height: 1025px;
}
textarea{
  width:1100px;
  height:1000px;
  overflow:auto;
}
</style>

路由设置

路由的设置我们一般都在router/index.js文件内设置。这个目录我们可以手动创建,也可以在项目创建的时候直接选定创建。

跟随项目一起创建:

 这里有一个Router选项,勾选上就可以。

手动创建:

我们创建对应目录以及文件,这个时候是不能使用的。我们还需要在main.js里面设置

  1. import router from './router'
    
  2. app.use(router)

设置完这两个就说明我们启用了路由系统。

具体路由的设置我们在index:对应的部分已经理解过了。这里就简单赘述一下

路由的设置是设置一个数组,数组存放对象们,对象里面包含两个参数,一个是path,另一个是component,path设置的是路径,compoent设置的是路径对应跳转哪个界面。

如果有嵌套路径的存在,就需要再在改对象里面添加一个属性

children: [
    
]

这个里面存放的数据和外部的是一样的,path,component如果还有嵌套内容就再写一个children。并且嵌套的路径不需要再写 斜杠/  直接写路径就可以了,这个斜杠会自动补充。

前端部分大概就讲这一点吧。更加深层的还是需要看更权威的专家的讲解或者去看官方文档。

后端部分

后端我们使用的是go语言的gin框架

大致的架构我们讲一下

主要是分为三个模块,一个是路由模块,一个是路由对应处理函数模块,一个是与数据库的连接模块。

我们首先来讲一下最重要的路由模块(其实都很重要)

main.go:

这个文件主要负责路由的设置。

package main

import (
	"github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"
)


// 同一目录下,同一包内的.go文件内函数是共享的
func main() {
	router := gin.Default()
	router.Use(cors.Default())
	router.POST("/Add", Addpost)         //
	router.POST("/Change", Change)       //这是前端查询并返回查询结果的路径
	router.POST("/Changeend", Changeend) //这是后端接收前端处理好的结果的路径
	router.POST("./Discover", Discover)
	router.POST("/Delete", Delete)
	router.Run(":8081") //运行指定端口
}

我们既然要使用gin框架就需要实现导入这个框架。也就是:import  "github.com/gin-gonic/gin"

,然后我们就可以设置路由了,这里需要注意设置的路由需要和前端对应上,而且要严格区分大小写!!!我们先通过router:= gin.Default()创建了一个默认的gin路由引擎。

然后我们设置了很多条路由,通过   .请求方法("路由",对应的处理函数)

最后使用router.Run(":8081")运行。

这里提到了端口,我们前端运行的时候也是需要端口的。双方端口不能一样,如果一样会导致端口占用错误,但是端口不一样虽然不会导致错误出现。却引发了一个新的问题:跨域

跨域问题的解决在前端后端都可以,但是我们还是默认在后端解决跨域问题。

router.Use(cors.Default())这条语句就是解决跨域问题的,它在"github.com/gin-contrib/cors"包下,所以要事先导入这个包。但是这部分博主并不是很精通,就不讲了。只能说通过router.Use(cors.Default())语句我们可以设置一些默认的设定解决跨域问题。

然后就是路由后面跟着的处理函数,这个函数我们是写在与main.go同级目录下并且都属于包main。所以可以直接使用不用导入对应的包。

至于为什么函数不加()是因为如果加了()就是直接使用这个函数。这并不是我们需要的。我们需要的是在特定情况下跳转到对应的处理函数。所以没有加上()

mysql.go:

package main

import (
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

type blog struct {
	BlogName string `gorm:"primaryKey type:varchar(255)"`
	BlogText string `gorm:"not null unique type:text"`
} //创建一个结构体,结构体用于存储博文和博文名称

func sqlof() *gorm.DB { //这是一个数据库连接函数,当我们调用它的时候会返回一个数据库对象。我们用这个对象进行数据的增上改查
	dsn := "root:123456@tcp(127.0.0.1:3306)/web_of_blog"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		panic(err)
	}
	db.AutoMigrate(&blog{})

	return db
}

这个文件的主要作用是连接数据库并提供一个函数,函数返回一个数据库对象。

我们需要创建一个结构体对象,这个对象的字段和数据库里面的字段一一对应。

dsn是一个字符串,字符串的内容是用户:密码@协议(ip,端口)/数据库名称

ip使用的是127.0.0.1是说明这是本机的数据库。

我们使用gorm.Open(mysql.Open(dsn),&gorm.Config{})连接数据库,它会返会一个对象和错误信息。如果连接成功是没有错误信息的,即err==nil

db.AutoMigrate(&blog{})的作用是确认数据库里有对应的表(结构体名称+s)如果没有则自动创建,如果表的结构不同则更新结构。

我们把最后的连接好的对象作为返回值返回给调用者。

controller.go

这个部分可以说是后端的灵魂所在了

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
)

var ch = make(chan string, 1)
var db = sqlof()      //创建数据库全局对象
type Article struct { //这个结构体用于接收前端数据博文和博文名称
	Name string `json:"name"`
	Text string `json:"text"`
}
type change_blog_title struct {
	Title string `json:"title"`
}

func Addpost(c *gin.Context) {
	var article Article
	if err := c.ShouldBindJSON(&article); err != nil {
		c.JSON(400, gin.H{"error": "解析 JSON 失败"})
		return
	}

	var insert blog //创建一个结构体对象,用于存储从前端读取的数据
	insert.BlogName = article.Name
	insert.BlogText = article.Text
	if db.Create(&insert).Error != nil { //判断数据库插入操作是否成功,成功返回200不成功返回500
		c.JSON(500, gin.H{
			"Error": "error",
		})
		/*这里返回的是json数据格式,所以前端读取的时候就需要使用.Error读取对应的key值*/
	} else {
		c.JSON(200, gin.H{
			"Error": "no error",
		})
	}
}

// Change /*前端发送一个title作为博文的名字给后端,后端读取这个数据然后查询,并返回查询结果*/
func Change(c *gin.Context) {

	fmt.Println("change函数被成功调用,说明后端路由设置无误")
	var title change_blog_title //这是一个博文的表头的结构体实例对象
	var content blog
	//通过前端发送的数据来把title赋值给后端的title然后再通过db对象进行查询,并把查询结果的信息返回给后端
	err := c.ShouldBindJSON(&title)
	if err != nil {
		fmt.Println("error")
	}
	fmt.Println("jianche", title.Title)
	ch <- title.Title

	db.Table("blogs").Where("blog_name = ?", title.Title).First(&content) //把查询到的第一个结果返回给content进行数据绑定
	c.JSON(200, gin.H{                                                    //返回查询到的文章和数据
		"Blog_body":  content.BlogText,
		"Blog_title": content.BlogName,
	})
	fmt.Println("数据已返回", content.BlogName, content.BlogText)

}
func Changeend(c *gin.Context) { //接收数据并修改,然后返回修改完成还是错误
	blog_name := <-ch
	date := blog{}
	if err := c.ShouldBindJSON(&date); err != nil {
		c.JSON(400, gin.H{
			"return": "数据写入错误",
		})
	}
	result := db.Table("blogs").Where("blog_name = ?", blog_name).Update("blog_text", date.BlogText)
	if result.Error != nil {
		c.JSON(500, gin.H{"return": "更新博文失败"})
		return
	}
	result = db.Table("blogs").Where("blog_name = ?", blog_name).Update("blog_name", date.BlogName)
	if result.Error != nil {
		c.JSON(500, gin.H{"return": "更新博文失败"})
		return
	} else {
		c.JSON(200, gin.H{
			"return": "修改成功",
		})
	}

}

func Discover(c *gin.Context) {
	fmt.Println("discover函数被成功调用,说明后端路由设置无误")
	var title change_blog_title //这是一个博文的表头的结构体实例对象
	var content blog
	//通过前端发送的数据来把title赋值给后端的title然后再通过db对象进行查询,并把查询结果的信息返回给后端
	err := c.ShouldBindJSON(&title)
	if err != nil {
		fmt.Println("error")
	}
	fmt.Println("jianche", title.Title)

	db.Table("blogs").Where("blog_name = ?", title.Title).First(&content) //把查询到的第一个结果返回给content进行数据绑定
	c.JSON(200, gin.H{                                                    //返回查询到的文章和数据
		"Blog_body": content.BlogText,
	})
	fmt.Println("数据已返回", content.BlogName, content.BlogText)

}

type DeleteRequest struct {
	BlogName string `json:"blog_name"`
}

func Delete(c *gin.Context) {
	var request DeleteRequest
	err := c.ShouldBindJSON(&request)
	if err != nil {
		c.JSON(400, gin.H{
			"return": "出现错误,啦啦啦",
		})
		return
	}

	blog_name := request.BlogName
	fmt.Println("i get it: ", blog_name)

	resout := db.Where("blog_name = ?", blog_name).Delete(&blog{})
	if resout.Error != nil {
		c.JSON(500, gin.H{
			"return": "error",
		})
	} else {
		c.JSON(200, gin.H{
			"return": "ok",
		})
	}
}

它根据不同路由的设置来执行对应的函数,这一整个文件的核心就是c *gin.Context这个

c *gin.Context 是 Gin 框架中处理 HTTP 请求的核心对象,它的主要作用包括:

  • 获取请求信息:如请求头、请求体、查询参数、路径参数等。

  • 生成响应:如返回 JSON、HTML、文本等。

  • 管理中间件:在请求处理过程中传递数据。

  • 控制流程:如中止请求、重定向等。

我们通过它获取前端发送的数据,并且返回给前端数据。

我们使用c.ShouldBindJSON(&结构体)把数据绑定到结构体,这需要我们提前创建一个空的结构体对象。对象的字段名称要与前端通过axios传递过来的json数据的key值相同

也就是我前端传递数据{"Name":"123","age":18}后端的结构体字段就需要是Name和age默认的类型都是string字符串类型。同样的,前端获取后端的回应也是如此。只不过我们前端使用的是

.then(res=>{

我们需要使用res.data.返回json数据的key获取对应的value

})

绑定完成之后我们就获取到了前端发送的请求了。

然后就是与数据库交互的部分了,这部分我们之前在gorm讲过

使用gorm连接数据库

至于为什么后端没有用mvc架构,是因为代码量不大,而且模块也就三个用不上架构。