Files
minivue/stage04/index.js
zzy 845789cd60 feat(stages): 添加性能测试和虚拟DOM实现阶段
添加stage04-perf用于真实DOM操作性能对比,包含三个不同的更新策略:
- innerHTML全量更新
- createElement全量重建
- 精确单节点更新

添加stage04用于模拟异步接口数据获取后的渲染演示

添加stage05实现虚拟DOM基础功能,提供VNode对象描述DOM树结构和递
归渲染函数
2026-05-02 12:36:53 +08:00

104 lines
2.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Stage 04模拟异步接口
* 演示数据从接口获取后再渲染
*/
/**
* 根据用户数据生成卡片 DOM 节点
* @param {{ name: string, age: number, tag: string }} user
* @returns {HTMLDivElement}
*/
function generateUser(user) {
const card = document.createElement("div");
card.className = "user-card";
const name = document.createElement("h2");
name.textContent = "姓名: " + user.name;
const age = document.createElement("p");
age.textContent = "年龄: " + user.age;
const tag = document.createElement("span");
tag.textContent = user.tag;
card.appendChild(name);
card.appendChild(age);
card.appendChild(tag);
return card;
}
/**
* 将用户卡片挂载到指定容器
* @param {{ name: string, age: number, tag: string }} user
* @param {HTMLElement} container
*/
function renderUser(user, container) {
container.appendChild(generateUser(user));
}
/**
* 渲染用户列表(先清空容器)
* @param {{ name: string, age: number, tag: string }[]} users
* @param {HTMLElement} container
*/
function renderUserList(users, container) {
container.innerHTML = ""; // 清空原有内容
for (let i = 0; i < users.length; i++) {
renderUser(users[i], container);
}
}
// 模拟数据库
const multiUser = [
{ name: "小明", age: 18, tag: "学生" },
{ name: "小王", age: 19, tag: "学生" },
{ name: "小李", age: 20, tag: "学生" },
{ name: "小孙", age: 56, tag: "校长" },
{ name: "小赵", age: 43, tag: "老师" },
];
/**
* 模拟异步获取用户数据
* @param {number} id
* @returns {Promise<{ name: string, age: number, tag: string }[]>}
*/
async function getUser(id) {
await new Promise((resolve) => setTimeout(resolve, 500));
const count = Math.min(Math.max(1, id), multiUser.length);
return multiUser.slice(0, count);
}
const root = document.getElementById("minivue");
const loadBtn = /** @type {HTMLButtonElement} */ (
document.getElementById("loadBtn")
);
const userIdInput = /** @type {HTMLInputElement} */ (
document.getElementById("userId")
);
userIdInput.value = "1";
loadBtn.addEventListener("click", async () => {
const rawValue = userIdInput.value.trim();
const id = parseInt(rawValue, 10);
if (isNaN(id) || id < 1) {
alert("请输入一个大于 0 的数字 ID");
return;
}
loadBtn.disabled = true;
loadBtn.textContent = "加载中...";
try {
const users = await getUser(id);
renderUserList(users, root);
} catch (err) {
console.error("加载失败", err);
alert("加载失败,请重试");
} finally {
loadBtn.disabled = false;
loadBtn.textContent = "加载用户";
}
});