公共子组件编写
头部组件
components/admin/Header.vue
<template>
<a-popconfirm title="确认退出?" ok-text="是" cancel-text="否" @confirm="loginout">
<a-button type="danger">登出</a-button>
<!-- <a href="#">Delete</a> -->
</a-popconfirm>
</template>
<script>
export default {
methods:{
loginout(){
window.sessionStorage.clear('token')
this.$router.push('/login')
this.$message.success("感谢您的使用")
}
}
}
</script>
侧边栏组件
components/admin/Nav.vue
<template>
<a-layout-sider breakpoint="lg" v-model="collapsed">
<div class="log">
<span>{{collapsed? "blog":"Salmon Blog"}}</span>
</div>
<a-menu theme="dark" mode="inline" @click="gotopage">
<a-menu-item key="index">
<a-icon type="dashboard"></a-icon><span>仪表盘</span>
</a-menu-item>
<a-sub-menu>
<span slot="title"><a-icon type="file" /><span>文章管理</span></span>
<a-menu-item key="addart">
<a-icon type="form"></a-icon><span>新增文章</span>
</a-menu-item>
<a-menu-item key="artlist">
<a-icon type="snippets"></a-icon><span>文章列表</span>
</a-menu-item>
</a-sub-menu>
<a-menu-item key="catelist">
<a-icon type="book"></a-icon><span>分类列表</span>
</a-menu-item>
<a-menu-item key="userlist">
<a-icon type="user"></a-icon><span>用户列表</span>
</a-menu-item>
</a-menu>
</a-layout-sider>
</template>
<script>
export default {
data(){
return{
collapsed: false
}
},
methods:{
gotopage(item){
this.$router.push('/admin/'+item.key).catch((err)=>err)
}
}
}
</script>
<style>
.log{
height: 32px;
margin: 16px;
background-color: #fff;
display: flex;
justify-content: center;
align-items: center;
font-size: 17px;
}
</style>
页脚组件
components/admin/Footer.vue
<template>
<div class="footer">
<span> -------Salmon------- </span>
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
.footer{
background-color: aliceblue;
text-align: center;
height: 100%;
}
.footer span{
height: 100%;
font-size: 20px;
}
</style>
用户列表页编写
components/user/UserList.vue
<template>
<div>
<h3>用户列表页</h3>
<a-card>
<a-row :gutter="20">
<a-col :span="6">
<a-input-search placeholder="请输入用户名" enter-button />
</a-col>
<a-col :span="4">
<a-button type="primary">新增</a-button>
</a-col>
</a-row>
<a-table
:columns='columns'
rowKey='username'
:pagination="PaginationOption"
:dataSource="userlist"
bordered
>
<span slot="role" slot-scope="role">{{role == 1 ? "管理员":"订阅者"}}</span>
<template slot="action">
<div class="actionSlot">
<a-button type="primary" style="margin-right:15px">编辑</a-button>
<a-button type="danger">删除</a-button>
</div>
</template>
</a-table>
</a-card>
</div>
</template>
<script>
const columns = [
{
title: 'ID',
dataIndex: 'ID',
key: 'id',
width: '10%',
align:'center'
},
{
title: '用户名',
dataIndex: 'username',
key: 'username',
width: '20%',
align:'center'
},
{
title: '角色',
dataIndex: 'role',
key: 'role',
width: '20%',
scopedSlots:{customRender:'role'},
align:'center'
},
{
title: '操作',
key: 'action',
width: '30%',
scopedSlots:{customRender:'action'},
align:'center'
},
]
export default {
data(){
return{
columns,
PaginationOption:{
pageSizeOptions:['5','10','20'],
defaultCurrent:1,
defaultPageSize:5,
total:0,
showSizeChanger:true,
showTotal:(total)=>`共${total}条`,
onChage:(page, pageSize)=>{
this.PaginationOption.defaultCurrent = page
this.PaginationOption.defaultPageSize = pageSize
this.getUserList()
},
onshowSizeChange:(current, size)=>{
this.PaginationOption.defaultCurrent = current
this.PaginationOption.defaultPageSize = size
this.getUserList()
}
},
userlist:[],
}
},
created(){
this.getUserList()
},
methods:{
async getUserList(){
const { data:res } = await this.$http.get('api/v1/user/', {
params:{
size:this.PaginationOption.defaultPageSize,
page:this.PaginationOption.defaultCurrent
},
})
if(res.code != 200)return this.$message.error(res.msg)
this.userlist = res.data
this.PaginationOption.total = res.total
}
}
}
</script>
<style>
.actionSlot{
display: flex;
justify-content: center;
}
</style>
搜索功能
这里和之前的查看全部用户功能大部分是重复的,重构一下后端函数
model/User.go
func GetUsers(username string, Size int, Page int)([]User,int64) {
var users []User
var total int64
if username != ""{
if username != "" {
db.Select("id,username,role").Where(
"username LIKE ?", username+"%",
).Limit(Size).Offset((Page - 1) * Size).Find(&users)
db.Model(&users).Where(
"username LIKE ?", username+"%",
).Count(&total)
return users, total
}
}
// 分页
err = db.Select("id,username,role").Offset((Page - 1) * Size).Limit(Size).Find(&users).Error
db.Model(&users).Count(&total)
if err != nil{
return users,0
}
// 返回用户的列表
return users,total
}
在接收的时候,接收一个username,绑定事件即可。
<a-col :span="6">
<a-input-search
v-model="queryParam.username"
allowClear placeholder="请输入用户名"
enter-button
@search="getUserList" />
</a-col>
删除功能
在删除按钮处添加弹窗和绑定事件
<template slot="action" slot-scope="data">
<div class="actionSlot">
<a-button type="primary" style="margin-right:15px">编辑</a-button>
<a-popconfirm title="确认删除?删除后无法恢复" ok-text="确认" cancel-text="取消" @confirm="delUser(data.ID)">
<a-button type="danger">删除</a-button>
</a-popconfirm>
</div>
</template>
<script>
async delUser(id){
const { data: res } = await this.$http.delete(`api/admin/user/${id}/`)
if(res.code != 200)return this.$message.error(res.msg)
this.queryParam.pagenum = 1
this.getUserList()
}
</script>
然后测试一下,ok,果然不行,忘了加权限的验证了。在main.js中,添加一个请求拦截器
// 请求拦截器
axios.interceptors.request.use(config => {
config.headers.Authorization = `Bearer ${window.sessionStorage.getItem('token')}`
return config
})
这样的话,每次都会携带上这个token,用来验证。
- Post link: https://www.godhearing.cn/gin-vue-da-jian-ge-ren-bo-ke-7/
- Copyright Notice: All articles in this blog are licensed under unless otherwise stated.