从零开始构建后台管理系统列表:新手友好教程,全程使用 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. 参与社区和交流

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

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

加油吧!

相关推荐
sg_knight7 分钟前
VSCode如何修改默认扩展路径和用户文件夹目录到D盘
前端·ide·vscode·编辑器·web
一个处女座的程序猿O(∩_∩)O17 分钟前
完成第一个 Vue3.2 项目后,这是我的技术总结
前端·vue.js
mubeibeinv17 分钟前
项目搭建+图片(添加+图片)
java·服务器·前端
逆旅行天涯24 分钟前
【Threejs】从零开始(六)--GUI调试开发3D效果
前端·javascript·3d
m0_748255261 小时前
easyExcel导出大数据量EXCEL文件,前端实现进度条或者遮罩层
前端·excel
长风清留扬1 小时前
小程序毕业设计-音乐播放器+源码(可播放)下载即用
javascript·小程序·毕业设计·课程设计·毕设·音乐播放器
web147862107231 小时前
C# .Net Web 路由相关配置
前端·c#·.net
m0_748247801 小时前
Flutter Intl包使用指南:实现国际化和本地化
前端·javascript·flutter
飞的肖1 小时前
前端使用 Element Plus架构vue3.0实现图片拖拉拽,后等比压缩,上传到Spring Boot后端
前端·spring boot·架构
青灯文案12 小时前
前端 HTTP 请求由 Nginx 反向代理和 API 网关到后端服务的流程
前端·nginx·http