「这是我参与11月更文挑战的第24天,活动详情查看:2021最后一次更文挑战」
前言
前一篇文章实现了接入后端的增删改查的接口,都较为简单,今天增加一个新的接口,根据分类列表的选择来控制详情数据的渲染,具体实现展示如下:
前端实现
主要是前端加了一个api请求方法,然后了一个新的页面,后端也有加了一个接口
主要代码
先亮出主要代码,再复述涉及到了哪些细节知识点
修改scr/view/index.vue文件内容如下:
<template>
<div class="app-container">
<el-form :inline="true" class="filter-form" :show-message="false">
<el-form-item label="类型:">
<el-select v-model="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>
<el-button type="primary" icon="el-icon-plus" @click="openAddFrom()">新增数据</el-button>
</el-form-item>
</el-form>
<el-table
v-loading="listLoading"
:data="list"
element-loading-text="加载中..."
border
fit
highlight-current-row
>
<el-table-column align="center" label="ID" width="95">
<template slot-scope="scope">
{{ scope.row.ID }}
</template>
</el-table-column>
<el-table-column label="Title">
<template slot-scope="scope">
{{ scope.row.Name }}
</template>
</el-table-column>
<el-table-column align="center" fixed="right" label="操作" width="190px">
<template slot-scope="scope">
<div class="flex-btns">
<el-button :loading="scope.row.loading" type="primary" @click="bindEdit(scope.row)">编辑</el-button>
<el-button type="info" @click="deteleType(scope.row)">删除</el-button>
</div>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import { getTypeList, getUrlList } from '@/api/url'
export default {
data() {
return {
filterText: '',
typelist: [],
list: [],
type: '全部'
}
},
watch: {
type(val) {
this.listLoading = true
getUrlList({
id: val
}).then(response => {
this.list = response.data.Value
this.listLoading = false
})
}
},
created() {
this.fetchData()
},
methods: {
fetchData() {
this.listLoading = true
getTypeList().then(response => {
this.typelist = response.data
})
getUrlList({
id: 0
}).then(response => {
this.list = response.data.Value
this.listLoading = false
})
}
}
}
</script>
src/api/url.js添加一个路由:
export function getUrlList(data) {
return request({
url: '/admin/getUrlList',
method: 'POST',
data
})
}
大部分代码跟上篇文章差不多,只引入了两个方法,新增了watch监听方法
v-model ,:value,:label
实现了页面的双向绑定,页面中使用了v-model绑定了一个名为type的变量,然后created生命周期钩子函数中初始化了type为全部这个值。
:是v-bind的缩写,:value和:lable是在select 的option循环中用于动态数据绑定。可以在Element-UI官网看到el-select的介绍,value和lable都是select的选项属性:
watch
用于监控一个值的变换,页面中监控了type,然后根据type的参数提供给getUrlList方法用于更新列表的数据,非常简单
后端实现
路由添加:
最开始使用的是GET方法,发现需要前端传json字符串才行,最后来改成了POST方法
admin.POST("/getUrlList", controller.GetUrlList)
控制器
func GetUrlList(c *gin.Context) {
var json request.GetUrlListRequest
if err := c.ShouldBindJSON(&json); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
result := global.NewResult(c)
list, err := service.GetUrlList(json)
if err != nil {
result.Error(5201, err.Error(), "域名列表获取失败")
return
}
result.Success(list)
}
服务方法
func GetUrlList(json request.GetUrlListRequest) (data interface{}, err error) {
list, nil := model.GetUrlList(json.Id)
return list, nil
}
验证器
type GetUrlListRequest struct {
Id int `form:"id" json:"id"`
}
有一个注意的地方就是验证器,id传0逻辑就是获取全部,但是验证器认为0就是没有传所以这里验证器字段就不能设置为必须,所以就去掉了`binding:"required"``。
模型方法
func GetUrlList(id int) (data interface{}, err error) {
var list []UrlList
if id != 0 {
res := db.Debug().Where("type_id = ?", id).Find(&list)
return res, nil
} else {
res := db.Debug().Find(&list)
return res, nil
}
}
id是0就查全部,不是零就查type_list的所有数据。
总结
进的这个带筛选的列表接口真正让我感觉到VUE的简单快捷,使用双向绑定就很简单的解决了数据的重新请求,之前JQuery的时候还需要读取HTML标签属性变量,设置HTML标签属性变量,模板渲染标签属性变量,非常繁琐~,下篇完善一下这个分类下详情数据的增删改。