$$demo <div class="operators"> <input id="name" type="text" placeholder="学生姓名" /> <input id="score" type="number" placeholder="分数" /> <button id="submit" onclick="controller.submit()">确认添加</button> <button id="cancel" onclick="controller.cancel()" hidden>取消编辑</button> </div> <table id="table"> <!-- <tr> <th>姓名</th> <th>分数</th> <th>操作</th> </tr> --> </table> <script> // Model: start // 数据管理 const model = { init() { this.loadStudents() }, students: [ { name: "小明", score: 56 }, { name: "鸣人", score: 80 }, { name: "路飞", score: 70 }, ], // 编辑的下标 _editIdx: null, get editIdx() { return this._editIdx }, set editIdx(value) { this._editIdx = value

        // 映射模型
        view.render()
    },
    get isEdit() {
        return this._editIdx !== null
    },
    set isEdit(value) {
        if (value) {
            console.error("不允许直接设置 isEdit 为 true")
            return
        } else {
            this.editIdx = null
        }
    },
    get editedStudent() {
        return model.students[model.editIdx]
    },
    loadStudents() {
        // 尝试读取数据
        if (localStorage.students) {
            this.students = JSON.parse(localStorage.students)
        }
        view.render()
    },
    saveStudents() {
        // 保存数据
        localStorage.students = JSON.stringify(this.students)
        view.render()
    },
    addStudent(name, score) {
        this.students.push({
            name,
            score,
        })
        // 更新后保存数据
        this.saveStudents()
    },
    editStudent(name, score) {
        this.students[this.editIdx] = {
            name,
            score,
        }

        // 更新后保存数据
        this.saveStudents()
    },
    removeStudent(index) {
        this.students.splice(index, 1)

        // 更新后保存数据
        this.saveStudents()
    },
}
// Model: end

// View: start
const view = {
    render() {
        // 映射模型数据到页面
        this.renderTable()
        this.renderOperators()
    },
    renderTable() {
        // 表格
        let html = `
            <tr>
                <th>姓名</th>
                <th>分数</th>
                <th>操作</th>
            </tr>
        `
        for (const index in model.students) {
            html += `
            <tr>
                <td>${model.students[index].name}</td>
                <td>${model.students[index].score}</td>
                <td>
                    <button onclick="controller.edit(${index})">
                        修改
                    </button>
                    <button onclick="controller.remove(${index})">
                        删除
                    </button>
                </td>
            </tr>`
        }

        document.getElementById("table").innerHTML = html
    },
    renderOperators() {
        // 输入框和按钮
        if (model.isEdit) {
            document.getElementById("name").value = model.editedStudent.name
            document.getElementById("score").value =
                model.editedStudent.score
            document.getElementById("submit").textContent = "确认编辑"
            document.getElementById("cancel").hidden = false
        } else {
            document.getElementById("submit").textContent = "确认添加"
            document.getElementById("name").value = ""
            document.getElementById("score").value = ""

            document.getElementById("cancel").hidden = true
        }
    },
}
// View: end

// Controller: start
const controller = {
    submit() {
        // 确认

        const nameEl = document.getElementById("name")
        const scoreEl = document.getElementById("score")

        if (nameEl.value === "") {
            alert("请输入姓名")
            return
        }

        if (scoreEl.value === "") {
            alert("请输入分数")
            return
        }

        if (model.isEdit) {
            model.editStudent(nameEl.value, scoreEl.value)
            model.isEdit = false
        } else {
            model.addStudent(nameEl.value, scoreEl.value)
        }
    },

    cancel() {
        // 取消编辑
        model.isEdit = false
    },

    edit(index) {
        // 编辑学生
        model.editIdx = index
    },

    remove(index) {
        // 删除学生

        const isDelete = confirm("确认删除吗?")
        if (isDelete) {
            model.removeStudent(index)
        }
    },
}
// Controller: end

model.init()

</script> <style> body { --primary-color: #eee; }

table {
    border-collapse: collapse;
    margin: 10px 0;
}

th {
    color: white;
    background-color: teal;
}

th,
td {
    border: 4px solid var(--primary-color);
    padding: 10px 60px;

    text-align: center;
}
button {
    padding: 5px 20px;
    cursor: pointer;
    background-color: var(--primary-color);

    border: none;
}

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

input {
    padding: 5px 10px;

    border: 2px solid var(--primary-color);
    outline: none;
}

.operators {
    display: flex;
    gap: 10px;
}

</style>

$$ $$answer

<div class="operators">
    <input id="name" type="text" placeholder="学生姓名" />
    <input id="score" type="number" placeholder="分数" />
    <button id="submit" onclick="controller.submit()">确认添加</button>
    <button id="cancel" onclick="controller.cancel()" hidden>取消编辑</button>
</div>
<table id="table">
    <!-- <tr>
        <th>姓名</th>
        <th>分数</th>
        <th>操作</th>
    </tr> -->
</table>
<script>
    // Model: start
    // 数据管理
    const model = {
        init() {
            this.loadStudents()
        },
        students: [
            { name: "小明", score: 56 },
            { name: "鸣人", score: 80 },
            { name: "路飞", score: 70 },
        ],
        // 编辑的下标
        _editIdx: null,
        get editIdx() {
            return this._editIdx
        },
        set editIdx(value) {
            this._editIdx = value

            // 映射模型
            view.render()
        },
        get isEdit() {
            return this._editIdx !== null
        },
        set isEdit(value) {
            if (value) {
                console.error("不允许直接设置 isEdit 为 true")
                return
            } else {
                this.editIdx = null
            }
        },
        get editedStudent() {
            return model.students[model.editIdx]
        },
        loadStudents() {
            // 尝试读取数据
            if (localStorage.students) {
                this.students = JSON.parse(localStorage.students)
            }
            view.render()
        },
        saveStudents() {
            // 保存数据
            localStorage.students = JSON.stringify(this.students)
            view.render()
        },
        addStudent(name, score) {
            this.students.push({
                name,
                score,
            })
            // 更新后保存数据
            this.saveStudents()
        },
        editStudent(name, score) {
            this.students[this.editIdx] = {
                name,
                score,
            }

            // 更新后保存数据
            this.saveStudents()
        },
        removeStudent(index) {
            this.students.splice(index, 1)

            // 更新后保存数据
            this.saveStudents()
        },
    }
    // Model: end

    // View: start
    const view = {
        render() {
            // 映射模型数据到页面
            this.renderTable()
            this.renderOperators()
        },
        renderTable() {
            // 表格
            let html = `
                <tr>
                    <th>姓名</th>
                    <th>分数</th>
                    <th>操作</th>
                </tr>
            `
            for (const index in model.students) {
                html += `
                <tr>
                    <td>${model.students[index].name}</td>
                    <td>${model.students[index].score}</td>
                    <td>
                        <button onclick="controller.edit(${index})">
                            修改
                        </button>
                        <button onclick="controller.remove(${index})">
                            删除
                        </button>
                    </td>
                </tr>`
            }

            document.getElementById("table").innerHTML = html
        },
        renderOperators() {
            // 输入框和按钮
            if (model.isEdit) {
                document.getElementById("name").value = model.editedStudent.name
                document.getElementById("score").value =
                    model.editedStudent.score
                document.getElementById("submit").textContent = "确认编辑"
                document.getElementById("cancel").hidden = false
            } else {
                document.getElementById("submit").textContent = "确认添加"
                document.getElementById("name").value = ""
                document.getElementById("score").value = ""

                document.getElementById("cancel").hidden = true
            }
        },
    }
    // View: end

    // Controller: start
    const controller = {
        submit() {
            // 确认

            const nameEl = document.getElementById("name")
            const scoreEl = document.getElementById("score")

            if (nameEl.value === "") {
                alert("请输入姓名")
                return
            }

            if (scoreEl.value === "") {
                alert("请输入分数")
                return
            }

            if (model.isEdit) {
                model.editStudent(nameEl.value, scoreEl.value)
                model.isEdit = false
            } else {
                model.addStudent(nameEl.value, scoreEl.value)
            }
        },

        cancel() {
            // 取消编辑
            model.isEdit = false
        },

        edit(index) {
            // 编辑学生
            model.editIdx = index
        },

        remove(index) {
            // 删除学生

            const isDelete = confirm("确认删除吗?")
            if (isDelete) {
                model.removeStudent(index)
            }
        },
    }
    // Controller: end

    model.init()
</script>
<style>
    body {
        --primary-color: #eee;
    }

    table {
        border-collapse: collapse;
        margin: 10px 0;
    }

    th {
        color: white;
        background-color: teal;
    }

    th,
    td {
        border: 4px solid var(--primary-color);
        padding: 10px 60px;

        text-align: center;
    }
    button {
        padding: 5px 20px;
        cursor: pointer;
        background-color: var(--primary-color);

        border: none;
    }

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

    input {
        padding: 5px 10px;

        border: 2px solid var(--primary-color);
        outline: none;
    }

    .operators {
        display: flex;
        gap: 10px;
    }
</style>

$$

本实例应用了 MVC 模式