从零开始构建后台管理系统列表:新手友好教程,全程使用 HTML+CSS+JavaScript,涵盖增删查改、导入导出、排序等功能(含完整源码)

b站视频演示效果:

效果图:

完整代码:

javascript 复制代码
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>后台管理系统</title>
    <!-- 引入正确的 Vue.js 版本 -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.min.js"></script>
    <!-- 引入样式 -->
    <style>
        /* 原有样式保持不变 */
        body {
            font-family: Arial, sans-serif;
            background-color: #f4f4f9;
            margin: 0;
            padding: 20px;
        }

        #app {
            max-width: 800px;
            margin: 0 auto;
        }

        h1 {
            text-align: center;
            color: #333;
        }

        table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 20px;
        }

        th, td {
            padding: 10px;
            border: 1px solid #ddd;
            text-align: left;
        }

        th {
            background-color: #5a67d8;
            color: white;
            cursor: pointer; /* 添加鼠标指针样式 */
            position: relative; /* 为排序箭头定位 */
        }

        th.sort-asc::after {
            content: '▲';
            position: absolute;
            right: 10px;
        }

        th.sort-desc::after {
            content: '▼';
            position: absolute;
            right: 10px;
        }

        button {
            padding: 10px 15px;
            margin: 5px;
            background-color: #5a67d8;
            color: white;
            border: none;
            cursor: pointer;
        }

        button:hover {
            background-color: #434190;
        }

        /* 弹框样式 */
        .modal {
            display: none; /* 默认隐藏 */
            position: fixed;
            z-index: 1;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
            overflow: auto;
            background-color: rgba(0,0,0,0.5); /* 半透明背景 */
        }

        .modal.show {
            display: block; /* 显示弹框 */
        }

        .modal-content {
            background-color: #fefefe;
            margin: 10% auto;
            padding: 20px;
            border: 1px solid #888;
            width: 400px;
            border-radius: 5px;
        }

        .modal-header h2 {
            margin: 0;
        }

        .modal-footer {
            text-align: right;
        }

        .input-group {
            margin-bottom: 15px;
        }

        .input-group label {
            display: block;
            margin-bottom: 5px;
            color: #333;
        }

        .input-group input, .input-group select {
            width: 100%;
            padding: 8px;
            box-sizing: border-box;
        }

    </style>
</head>
<body>
    <div id="app">
        <h1>后台管理系统</h1>
        <div class="action-buttons">
            <button @click="showAddModal">添加商品</button>
            <button @click="exportTable">导出表格</button>
            <input type="file" @change="importTable" style="display: inline-block; margin-left: 10px;" />
        </div>
        <table>
            <thead>
                <tr>
                    <th @click="sortBy('name')" :class="getSortClass('name')">名称</th>
                    <th @click="sortBy('price')" :class="getSortClass('price')">价格</th>
                    <th @click="sortBy('description')" :class="getSortClass('description')">描述</th>
                    <th @click="sortBy('category')" :class="getSortClass('category')">类别</th>
                    <th @click="sortBy('stock')" :class="getSortClass('stock')">库存</th>
                    <th>操作</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="(item, index) in sortedItems" :key="index">
                    <td>{{ item.name }}</td>
                    <td>{{ item.price.toFixed(2) }}</td>
                    <td>{{ item.description }}</td>
                    <td>{{ item.category }}</td>
                    <td>{{ item.stock }}</td>
                    <td>
                        <button @click="showEditModal(index)">编辑</button>
                        <button @click="removeItem(index)">删除</button>
                    </td>
                </tr>
            </tbody>
        </table>

        <!-- 添加商品的模态框 -->
        <div class="modal" :class="{ show: isAddModalVisible }">
            <div class="modal-content">
                <div class="modal-header">
                    <h2>添加商品</h2>
                </div>
                <div class="modal-body">
                    <div class="input-group">
                        <label>名称</label>
                        <input v-model="newItem.name" placeholder="请输入名称" />
                    </div>
                    <div class="input-group">
                        <label>价格</label>
                        <input v-model.number="newItem.price" placeholder="请输入价格" type="number" />
                    </div>
                    <div class="input-group">
                        <label>描述</label>
                        <input v-model="newItem.description" placeholder="请输入描述" />
                    </div>
                    <div class="input-group">
                        <label>类别</label>
                        <select v-model="newItem.category">
                            <option disabled value="">请选择类别</option>
                            <option>电子产品</option>
                            <option>服装</option>
                            <option>食品</option>
                            <option>书籍</option>
                        </select>
                    </div>
                    <div class="input-group">
                        <label>库存</label>
                        <input v-model.number="newItem.stock" placeholder="请输入库存数量" type="number" />
                    </div>
                </div>
                <div class="modal-footer">
                    <button @click="addItem">添加</button>
                    <button @click="isAddModalVisible = false">取消</button>
                </div>
            </div>
        </div>

        <!-- 编辑商品的模态框 -->
        <div class="modal" :class="{ show: isEditModalVisible }">
            <div class="modal-content">
                <div class="modal-header">
                    <h2>编辑商品</h2>
                </div>
                <div class="modal-body">
                    <div class="input-group">
                        <label>名称</label>
                        <input v-model="editItemData.name" placeholder="请输入名称" />
                    </div>
                    <div class="input-group">
                        <label>价格</label>
                        <input v-model.number="editItemData.price" placeholder="请输入价格" type="number" />
                    </div>
                    <div class="input-group">
                        <label>描述</label>
                        <input v-model="editItemData.description" placeholder="请输入描述" />
                    </div>
                    <div class="input-group">
                        <label>类别</label>
                        <select v-model="editItemData.category">
                            <option disabled value="">请选择类别</option>
                            <option>电子产品</option>
                            <option>服装</option>
                            <option>食品</option>
                            <option>书籍</option>
                        </select>
                    </div>
                    <div class="input-group">
                        <label>库存</label>
                        <input v-model.number="editItemData.stock" placeholder="请输入库存数量" type="number" />
                    </div>
                </div>
                <div class="modal-footer">
                    <button @click="updateItem">更新</button>
                    <button @click="isEditModalVisible = false">取消</button>
                </div>
            </div>
        </div>
    </div>

    <!-- 引入 Vue.js 脚本 -->
    <script>
    new Vue({
        el: '#app',
        data: {
            items: [],
            newItem: {
                name: '',
                price: 0,
                description: '',
                category: '',
                stock: 0
            },
            editIndex: null,
            editItemData: {
                name: '',
                price: 0,
                description: '',
                category: '',
                stock: 0
            },
            isAddModalVisible: false,
            isEditModalVisible: false,
            sortKey: '', // 当前排序的列
            sortOrders: { // 每列的排序顺序,1 为升序,-1 为降序
                name: 1,
                price: 1,
                description: 1,
                category: 1,
                stock: 1
            }
        },
        computed: {
            sortedItems() {
                let items = this.items.slice();
                if (this.sortKey) {
                    items.sort((a, b) => {
                        let result = 0;
                        let aVal = a[this.sortKey];
                        let bVal = b[this.sortKey];

                        // 处理空值
                        if (aVal === undefined || aVal === null) aVal = '';
                        if (bVal === undefined || bVal === null) bVal = '';

                        // 数值排序
                        if (typeof aVal === 'number' && typeof bVal === 'number') {
                            result = aVal - bVal;
                        } else {
                            // 字符串排序,使用 localeCompare 支持中文
                            result = aVal.toString().localeCompare(bVal.toString(), 'zh-Hans-CN', {numeric: true});
                        }
                        return result * this.sortOrders[this.sortKey];
                    });
                }
                return items;
            }
        },
        methods: {
            showAddModal() {
                // 重置 newItem 数据
                this.newItem = {
                    name: '',
                    price: 0,
                    description: '',
                    category: '',
                    stock: 0
                };
                this.isAddModalVisible = true;
            },
            addItem() {
                if (this.newItem.name && this.newItem.price >= 0 && this.newItem.category && this.newItem.stock >= 0) {
                    this.items.push({ ...this.newItem });
                    this.isAddModalVisible = false;
                } else {
                    alert('请填写完整的商品信息');
                }
            },
            removeItem(index) {
                this.items.splice(index, 1);
            },
            showEditModal(index) {
                this.editIndex = index;
                this.editItemData = { ...this.items[index] };
                this.isEditModalVisible = true;
            },
            updateItem() {
                if (this.editItemData.name && this.editItemData.price >= 0 && this.editItemData.category && this.editItemData.stock >= 0) {
                    this.$set(this.items, this.editIndex, this.editItemData);
                    this.isEditModalVisible = false;
                    this.editIndex = null;
                } else {
                    alert('请填写完整的商品信息');
                }
            },
            exportTable() {
                const headers = ['名称', '价格', '描述', '类别', '库存'];
                const csvContent = "data:text/csv;charset=utf-8," 
                    + headers.join(",") + "\n"
                    + this.items.map(item => 
                        `${item.name},${item.price},${item.description},${item.category},${item.stock}`
                    ).join("\n");
                const encodedUri = encodeURI(csvContent);
                const link = document.createElement("a");
                link.setAttribute("href", encodedUri);
                link.setAttribute("download", "data.csv");
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
            },
            importTable(event) {
                const file = event.target.files[0];
                if (!file) return;

                const reader = new FileReader();
                reader.onload = (e) => {
                    const text = e.target.result;
                    const rows = text.trim().split("\n").map(row => row.split(","));
                    const headers = rows[0];
                    const dataRows = rows.slice(1);
                    this.items = dataRows.map(row => ({
                        name: row[0],
                        price: parseFloat(row[1]),
                        description: row[2],
                        category: row[3],
                        stock: parseInt(row[4])
                    }));
                };
                reader.readAsText(file);
            },
            sortBy(key) {
                if (this.sortKey === key) {
                    this.sortOrders[key] = -this.sortOrders[key]; // 切换排序顺序
                } else {
                    this.sortKey = key;
                }
            },
            getSortClass(key) {
                if (this.sortKey === key) {
                    return this.sortOrders[key] === 1 ? 'sort-asc' : 'sort-desc';
                }
                return '';
            }
        }
    });
    </script>
</body>
</html>

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

各位同学们:还有啥想看的功能或者特效不?欢迎在评论区留言哦!

本人承接网网站开发,如有需要,欢迎私信咨询!

如果您感觉文章对您有帮助~
那就打赏一下,请笔者喝杯咖啡吧~

给新手学习前端开发的建议:

  1. 了解基础知识:

    • 学习HTML、CSS和JavaScript的基础知识。它们是前端开发的核心,构成了网页的基本结构和样式,以及交互功能。
    • 掌握HTML的标签和语义化,了解CSS的选择器和布局技巧,熟悉JavaScript的基本语法和DOM操作。
  2. 实践项目:

    • 不要仅仅停留在理论学习上,通过实践项目来巩固和应用所学知识。
    • 可以从简单的静态页面开始,逐渐尝试添加交互效果和动态数据。
    • 参与开源项目或自己动手创建一个个人网站,将所学知识应用到实际场景中。
  3. 学习工具和框架:

    • 了解并学习前端开发中常用的工具和框架,如构建工具(Webpack、Gulp等)、版本控制工具(Git)、前端框架(React、Vue、Angular等)。
    • 这些工具和框架能够提高开发效率,简化开发流程,是前端开发的重要组成部分。
  4. 关注前端趋势:

    • 前端开发是一个快速发展的领域,新的技术和工具不断涌现。
    • 关注前端社区、博客和会议,了解最新的技术趋势和发展方向,保持学习的热情和动力。
  5. 培养解决问题的能力:

    • 前端开发常常会遇到各种问题和挑战,学会独立思考和解决问题是非常重要的。
    • 遇到问题时,可以先尝试自己解决,通过查阅文档、搜索资料和社区讨论来找到答案。
    • 如果实在无法解决,可以向同事或社区求助,但也要学会总结和分享自己的经验和教训。
  6. 不断学习和提升:

    • 前端开发是一个不断学习和提升的过程,要保持对知识的渴望和追求。
    • 可以通过阅读书籍、参加培训、参与开源项目等方式来不断提升自己的技能水平。
    • 同时,也要关注自己的职业发展,了解行业的需求和趋势,规划自己的职业道路。
  7. 注重代码质量和可维护性:

    • 编写高质量的代码是前端开发的基本要求之一。
    • 学习并遵循代码规范,使用适当的命名和注释来提高代码的可读性。
    • 注重代码的结构和逻辑,避免过度嵌套和复杂的逻辑。
    • 考虑代码的可维护性,尽量编写可复用和可扩展的代码。
  8. 参与社区和交流:

    • 加入前端开发的社区和论坛,与其他开发者进行交流和分享。
    • 通过参与社区活动、回答问题、分享经验等方式,不仅可以提升自己的技能水平,还可以结识更多的同行和朋友。

总之,学习前端开发需要耐心和毅力,要保持对技术的热情和兴趣,不断学习和提升自己。通过实践项目、学习工具和框架、关注前端趋势等方式,你可以逐渐成为一名优秀的前端开发者。

加油吧!

相关推荐
卸任9 小时前
Vibe coding工具使用心得
前端·ai编程
brien910 小时前
为什么模型标称 1M,Google Antigravity 聊到 256K 却突然失忆?我们给它做了个原生行内监控圆环
前端
修炼的dance10 小时前
录屏关键帧间隔多少合适?六档实测,2秒到10秒小了75.6%
前端
Lank_M10 小时前
关键帧从1秒拉到10秒,录屏小87.3%,摄像头小10.8%
前端
补码缩写10 小时前
用 ffprobe 拆录屏,八成字节在 29 个关键帧上
前端
百思不得小李10 小时前
一个复杂的动态表单是如何实现的
前端·设计模式
陈随易10 小时前
Cmder 停更 17 个月,2.0 支持 Windows Terminal
前端·后端·程序员
清晨Coding11 小时前
删了 Cookie 还能自动登录?Google系网站登录态自动恢复的原理分析
javascript
风骏时光牛马11 小时前
前沿视界
前端
kyriewen11 小时前
我扫了 814 个依赖,97 个还敢要 Node 10
前端·javascript·程序员