后台交互 - 实际例子:管理后台

通过一个完整的"用户管理后台"例子,展示常见的后台交互模式,包括列表查询、分页、搜索、新增、编辑、删除等操作。

接口设计 (RESTful API)

方法 路径 说明
GET /api/users 获取用户列表(支持分页、搜索)
GET /api/users/:id 获取单个用户详情
POST /api/users 创建新用户
PUT /api/users/:id 更新用户信息
DELETE /api/users/:id 删除用户

1. 用户列表页 (HTML/Vue)

<div id="app"> <div class="toolbar"> <input v-model="searchKeyword" placeholder="搜索用户名或邮箱" @input="handleSearch"/> <button @click="openModal()">新增用户</button> </div> <table> <thead> <tr> <th>ID</th> <th>用户名</th> <th>邮箱</th> <th>状态</th> <th>操作</th> </tr> </thead> <tbody> <tr v-for="user in users" :key="user.id"> <td>{{ user.id }}</td> <td>{{ user.name }}</td> <td>{{ user.email }}</td> <td> <span :class="['status', user.active ? 'active' : 'inactive']"> {{ user.active ? '启用' : '禁用' }} </span> </td> <td> <button @click="editUser(user)">编辑</button> <button @click="deleteUser(user.id)">删除</button> </td> </tr> </tbody> </table> <div class="pagination"> <button :disabled="page === 1" @click="changePage(-1)">上一页</button> <span>第 {{ page }} / {{ totalPages }} 页</span> <button :disabled="page === totalPages" @click="changePage(1)">下一页</button> </div> </div>

2. 页面逻辑 (JavaScript)

const app = new Vue({ el: '#app', data: { users: [], searchKeyword: '', page: 1, pageSize: 10, total: 0, loading: false }, computed: { totalPages() { return Math.ceil(this.total / this.pageSize); } }, mounted() { this.fetchUsers(); }, methods: { // 获取用户列表(带分页和搜索) async fetchUsers() { this.loading = true; try { const params = new URLSearchParams({ page: this.page, pageSize: this.pageSize, keyword: this.searchKeyword }); const res = await fetch(`/api/users?${params}`); const data = await res.json(); this.users = data.list; this.total = data.total; } catch(e) { console.error('获取失败', e); } finally { this.loading = false; } }, // 搜索(防抖) handleSearch: debounce(function() { this.page = 1; this.fetchUsers(); }, 300), // 分页 changePage(delta) { this.page += delta; this.fetchUsers(); }, // 删除用户 async deleteUser(id) { if(!confirm('确定删除该用户?')) return; await fetch(`/api/users/${id}`, { method: 'DELETE' }); this.fetchUsers(); }, // 编辑用户 editUser(user) { // 打开弹窗并填充数据... }, // 打开新增弹窗 openModal() { // 打开弹窗... } } }); // 防抖函数 function debounce(fn, delay) { let timer; return function(...args) { clearTimeout(timer); timer = setTimeout(() => fn.apply(this, args), delay); }; }

3. 新增/编辑弹窗

<!-- 新增编辑弹窗 --> <div v-if="showModal" class="modal-overlay" @click="closeModal"> <div class="modal" @click.stop> <h3>{{ isEdit ? '编辑用户' : '新增用户' }}</h3> <form @submit.prevent="submitForm"> <div class="form-group"> <label>用户名</label> <input v-model="formData.name" required/> </div> <div class="form-group"> <label>邮箱</label> <input type="email" v-model="formData.email" required/> </div> <div class="form-group"> <label> <input type="checkbox" v-model="formData.active"/> 启用账户 </label> </div> <div class="form-actions"> <button type="button" @click="closeModal">取消</button> <button type="submit">提交</button> </div> </form> </div> </div>

4. 表单提交逻辑

data: { showModal: false, isEdit: false, formData: { id: null, name: '', email: '', active: true } }, methods: { openModal() { this.isEdit = false; this.formData = { id: null, name: '', email: '', active: true }; this.showModal = true; }, editUser(user) { this.isEdit = true; this.formData = { ...user }; this.showModal = true; }, closeModal() { this.showModal = false; }, async submitForm() { const url = this.isEdit ? `/api/users/${this.formData.id}` : '/api/users'; const method = this.isEdit ? 'PUT' : 'POST'; const res = await fetch(url, { method, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(this.formData) }); if (res.ok) { alert(this.isEdit ? '修改成功' : '创建成功'); this.closeModal(); this.fetchUsers(); } } }

5. 后端接口示例 (Node.js/Express)

// GET /api/users - 获取用户列表 app.get('/api/users', async (req, res) => { const { page = 1, pageSize = 10, keyword = '' } = req.query; let query = {}; if (keyword) { query.$or = [ { name: { $regex: keyword } }, { email: { $regex: keyword } } ]; } const total = await User.countDocuments(query); const list = await User.find(query) .skip((page - 1) * pageSize) .limit(Number(pageSize)); res.json({ list, total }); }); // POST /api/users - 创建用户 app.post('/api/users', async (req, res) => { const user = new User(req.body); await user.save(); res.json(user); }); // PUT /api/users/:id - 更新用户 app.put('/api/users/:id', async (req, res) => { const user = await User.findByIdAndUpdate(req.params.id, req.body, { new: true }); res.json(user); }); // DELETE /api/users/:id - 删除用户 app.delete('/api/users/:id', async (req, res) => { await User.findByIdAndDelete(req.params.id); res.json({ success: true }); });

效果演示

用户管理后台
ID 用户名 邮箱 状态 操作
1 张三 zhangsan@example.com 启用
2 李四 lisi@example.com 启用
3 王五 wangwu@example.com 禁用
第 1 / 5 页
← Backend Sse Wechat Overview →