从零开始摸索VUE,配合Golang搭建导航网站(二十五.vue-admin-template分类详情数据删改查)

1,304 阅读4分钟

「这是我参与11月更文挑战的第25天,活动详情查看:2021最后一次更文挑战

前言

前一篇文章做了一个根据分类筛选导航域名详情的列表展示,今天难度进一步加大,做一个可以分类下域名详情的删改查,重点是要在Element-UI的Dialog 对话框中加上一个选择框。

前端部分

今天前端和后端代码都一样多,代码太多了只展示添加的部分,不展示整个页面了。首先是需要在列表页增加更仔细的信息:

增加table列

image.png 分类和url,需要增加两个el-table-column,lable就是列的名字,前面几篇就说过插槽了,这里不复述了。

  <el-table-column label="分类ID">
    <template slot-scope="scope">
      {{ scope.row.TypeID }}
    </template>
  </el-table-column>
  <el-table-column label="Url">
    <template slot-scope="scope">
      {{ scope.row.URL }}
    </template>
  </el-table-column>

增加两个对话框


    <!--  添加导航网址  -->
    <el-dialog title="添加导航url" :visible.sync="formAddVisible" width="450px" center>
      <el-form ref="addform" :inline="true">
        <el-form-item label="选择分类">
          <el-select v-model="add_type" placeholder="请选择类型" style="max-width:140px">
            <el-option v-for="item in typelist" :key="item.ID" :value="item.ID" :label="item.Name" />
          </el-select>
        </el-form-item>
        <el-form-item label="输入名称">
          <el-input v-model="addForm.name" placeholder="请输入导航名称" />
        </el-form-item>
        <el-form-item label="输入域名">
          <el-input v-model="addForm.url" placeholder="请输入导航url" />
        </el-form-item>
      </el-form>
      <el-button native-type="primary" @click="onSubmitAdd">确认添加</el-button>
    </el-dialog>

    <!--  修改导航url  -->
    <el-dialog title="编辑导航url" :visible.sync="formEditVisible" width="450px" center>
      <el-form ref="addform" :inline="true">
        <el-form-item label="选择分类">
          <el-select v-model="edit_type" placeholder="请选择类型" style="max-width:140px">
            <el-option v-for="item in typelist" :key="item.ID" :value="item.ID" :label="item.Name" />
          </el-select>
        </el-form-item>
        <el-form-item label="输入名称">
          <el-input v-model="editForm.name" placeholder="请输入导航名称" />
        </el-form-item>
        <el-form-item label="输入域名">
          <el-input v-model="editForm.url" placeholder="请输入导航url" />
        </el-form-item>
      </el-form>
      <el-button native-type="primary" @click="onSubmitEdit">确认修改</el-button>
    </el-dialog>

效果如图:

image.png

image.png 原生的还是挺好看的。我在每个对话框中的el-form中增加了一个:inline="true"属性,使input和它的说明的label显示在了同一行,但是提交的button为了不让它跟最后一个表格输入框在一行我把它 放在了form的外面。
然后使用了双向绑定,点击编辑的时候会把点击的那一列的数据渲染在对话框中:

    bindEdit(data) {
      this.editForm.id = data.ID
      this.editForm.name = data.Name
      this.editForm.url = data.URL
      this.editForm.type_id = data.TypeID
      this.edit_type = data.TypeID
      this.formEditVisible = true
    },

最重要的使会把那一列数据的type_id记下来去回显到单选框。而且跟另外一个单选框独立,更改数据时的分类单选框和添加分类单选框互相独立,添加分类单选框打开永远是全部,全部传递给后端的type_id就是0然后会报错,直到选择了有值的分类id。这里需要注意的是所有使用到了变量数据都需要在vue对象中data属性中定义,所以为了实现这些功能在data中定义了很多变量:

  data() {
    return {
      add_type: '全部',
      edit_type: '',
      typelist: [],
      list: [],
      type: 0,
      formAddVisible: false,
      formEditVisible: false,
      addForm: {
        type_id: 0,
        name: '',
        url: ''
      },
      editForm: {
        id: 0,
        type_id: 0,
        name: '',
        url: ''
      }
    }
  },

数据监听

  watch: {
    type(val) {
      this.fetchData()
    },
    add_type(val) {
      this.addForm.type_id = val
    }
  },

监听了两个变量,第一个是上篇文章的根据单选框选择重新渲染带条件的列表。第二个实现的是添加详情数据时选择分类更改type_id提供给提交表单时使用,所以这里在添加数据方法的时候获取的type_id是从数据监听这里获取的,并没有从单选框获取:

    onSubmitEdit() {
      editUrl({
        id: this.editForm.id,
        type_id: this.edit_type,
        name: this.editForm.name,
        url: this.editForm.url
      }).then(res => {
        this.$message({
          type: 'success',
          message: '修改成功'
        })
        this.fetchData()
        this.formEditVisible = false
      })
    }

后端

简单讲一讲,不亮出全部的代码了,路由器添加了3行代码,分别是删除详情,增加详情,修改详情

admin.POST("/DelUrl", controller.DelUrl)
admin.POST("/AddUrl", controller.AddUrl)
admin.POST("/EditUrl", controller.EditUrl)

验证器这里都需要传值,而且字段都是必须的:

type DelUrlRequest struct {
	Id int `form:"id" json:"id" binding:"required"`
}

type AddUrlRequest struct {
	Name   string `form:"name" json:"name" binding:"required"`
	TypeID int    `form:"type_id" json:"type_id" binding:"required"`
	Url    string `form:"url" json:"url" binding:"required"`
}

type EditUrlRequest struct {
	Id     int    `form:"id" json:"id" binding:"required"`
	Name   string `form:"name" json:"name" binding:"required"`
	TypeID int    `form:"type_id" json:"type_id" binding:"required"`
	Url    string `form:"url" json:"url" binding:"required"`
}

控制器加了三个方法,使用的验证器删除的验证器可以使用删除分类的验证器,但是为了规范还是没有偷懒:

func DelUrl(c *gin.Context) {
	var json request.DelUrlRequest
	if err := c.ShouldBindJSON(&json); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	result := global.NewResult(c)
	err := service.DelUrl(json)
	if err != nil {
		result.Error(5201, err.Error(), "删除失败")
		return
	}
	result.Success("删除成功")
}

func AddUrl(c *gin.Context) {
	var json request.AddUrlRequest
	if err := c.ShouldBindJSON(&json); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	result := global.NewResult(c)
	id, err := service.AddUrl(json)
	if err != nil {
		result.Error(5201, err.Error(), "域名获取失败")
		return
	}
	result.Success(id)
}

func EditUrl(c *gin.Context) {
	var json request.EditUrlRequest
	if err := c.ShouldBindJSON(&json); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	result := global.NewResult(c)
	err := service.EditUrl(json)
	if err != nil {
		result.Error(5201, err.Error(), "域名修改失败")
		return
	}
	result.Success("域名修改成功")
}

服务方法,需要根据ORM方法需要的数据按照顺序传入,不然就会混乱,而且需要根据控制器曾需要的内容返回,有的传新增数据的ID,有的只需要传是否报错:

func DelUrl(json request.DelUrlRequest) (err error) {

	nil := model.DelUrl(json.Id)
	return nil
}

func AddUrl(json request.AddUrlRequest) (id int, err error) {

	id, nil := model.AddUrl(json.Name, json.Url, json.TypeID)
	return id, nil
}
func EditUrl(json request.EditUrlRequest) (err error) {

	nil := model.EditUrl(json.Id, json.TypeID, json.Name, json.Url)
	return nil
}

最后model层,注意替换模型对象和字段内容,删除是最简单的:

//删除一个详情
func DelUrl(id int) error {
	return db.Delete(&UrlList{}, id).Error
}

//增加一个详情
func AddUrl(name string, url string, type_id int) (id int, err error) {
	ListData := UrlList{
		Name:   name,
		TypeID: type_id,
		URL:    url,
	}
	err = db.Debug().Create(&ListData).Error
	return int(ListData.ID), err
}

//修改一个详情
func EditUrl(id int, type_id int, name string, url string) error {
	return db.Debug().Model(&UrlList{}).Where("id = ?", id).Updates(map[string]interface{}{
		"TypeID": type_id,
		"Name":   name,
		"Url":    url,
	}).Error
}

总结

今天这篇文章我认为重难点就是单选框的数据回显控制,最开始是让两个对话框中的单选框互相影响了,感觉体验很差,最后多定义了一些变量,加上变量监控才解决了这个问题。还是小小的绕了一个弯,在其中还是感觉到了VUE的强大之处,所有的数据都是放在Vue对象中,是真实存在并随时都可以调用操作的,非常方便,在jQuery中对一些概念封装很模糊,通常都是写很多方法操作数据,然后要实现一些稍微复杂的功能导致方法会写的很长,最终导致逻辑混乱,不知道哪里操作了数据~
下篇准备完善用户登录,让它更像完整的商业项目。