HTML / CSS / JavaScript 前端基础
三大核心技术入门 — 给中际旭创制造可视化工程师的前端速成手册
01 · HTML — 骨架
HTML = 网页的骨架,就像 Excel 表格的「sheet 结构」——决定有哪些行、哪些列、放什么内容。
CSS 负责好看不好看,JS 负责聪明不聪明,但没有 HTML 就什么都没有。
基本 HTML 页面结构
<!DOCTYPE html> <!-- 告诉浏览器:这是 HTML5 -->
<html lang="zh-CN"> <!-- 根元素 -->
<head> <!-- 头部:元信息(用户看不到) -->
<meta charset="UTF-8"> <!-- 编码 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我的看板</title> <!-- 浏览器标签页标题 -->
<link rel="stylesheet" href="style.css"> <!-- 引入 CSS -->
</head>
<body> <!-- 身体:用户看到的所有内容 -->
<h1>车间看板</h1>
<script src="app.js"></script> <!-- 引入 JS -->
</body>
</html>
常用标签速查
| HTML 标签 | Excel 对应 | 用途 |
|---|---|---|
<div> | 一个区域/分组 | 通用容器,最常用的布局元素 |
<span> | 单元格里的部分文字 | 行内容器,不会换行 |
<h1>~<h6> | 标题行(加粗大字) | 标题,h1 最大,h6 最小 |
<p> | 一段文本 | 段落 |
<table> | Excel Sheet 本身 | 表格 |
<form> | 数据录入表单 | 表单容器 |
<input> | 单元格(可编辑) | 输入框 |
<button> | 按钮/宏触发器 | 按钮 |
<img> | 插入的图片 | 图片 |
<a> | 超链接 | 链接到其他页面 |
实战:一个简单的 Dashboard 卡片布局
<div class="dashboard">
<!-- OEE 概览卡片 -->
<div class="card">
<h3>设备 OEE</h3>
<p class="value">85.2%</p>
<span class="trend up">↑ 3.1%</span>
</div>
<!-- 产量卡片 -->
<div class="card">
<h3>今日产量</h3>
<p class="value">12,450</p>
<span class="trend down">↓ 120</span>
</div>
<!-- 告警卡片 -->
<div class="card alert">
<h3>异常告警</h3>
<p class="value">3</p>
<button onclick="showAlerts()">查看详情</button>
</div>
</div>
HTML 只管结构:这个页面有哪些区块、什么内容。至于颜色、大小、位置——那是 CSS 的事。至于点击按钮会发生什么——那是 JS 的事。
就像 Excel:你先输入数据(HTML),再设置格式(CSS),最后写宏(JS)。
02 · CSS — 皮肤 / 衣服
CSS = 网页的衣服,就像 Excel 里的「设置单元格格式」:字体、颜色、边框、列宽、对齐方式。
三种引入方式
/* ① 行内样式(不推荐,像直接在单元格里改格式) */
<p style="color: red; font-size: 18px;">红色文字</p>
/* ② 内部样式表(写在 <style> 里,像 Excel 的"单元格样式") */
<style>
p { color: red; font-size: 18px; }
</style>
/* ③ 外部样式表(推荐,像 Excel 模板文件 .xltx) */
<link rel="stylesheet" href="style.css">
CSS Box Model(盒模型)
每个 HTML 元素都是一个「盒子」。理解盒模型是理解 CSS 布局的基础:
(内容)
| Box Model 层 | Excel 对应 | 说明 |
|---|---|---|
content | 单元格里的文字 | 实际内容区域 |
padding | 单元格内边距(对齐方式) | 内容和边框之间的空间 |
border | 单元格边框线 | 边框粗细、样式、颜色 |
margin | 列宽 / 行高的一部分 | 元素与元素之间的间距 |
.card {
width: 300px; /* 内容宽度 */
padding: 20px; /* 内边距 20px(上下左右) */
border: 2px solid #ddd; /* 边框:粗细 样式 颜色 */
margin: 16px; /* 外边距 16px */
box-sizing: border-box; /* 关键!让 width 包含 padding+border */
}
/* ⚡ 实际开发中,通常全局设置 box-sizing: border-box */
* { box-sizing: border-box; }
Flexbox — Dashboard 布局必备
Flexbox 是最常用的一维布局方案。想象把 4 个 OEE 卡片排成一行:
.oee-cards {
display: flex; /* 开启 Flex 布局 */
justify-content: space-between; /* 水平方向:两端对齐 */
align-items: center; /* 垂直方向:居中 */
gap: 16px; /* 元素之间的间距 */
}
.oee-cards .card {
flex: 1; /* 每个卡片等宽 */
}
/* 其他常用值: */
/* justify-content: flex-start | center | flex-end | space-around */
/* align-items: stretch | flex-start | flex-end | center | baseline */
/* flex-direction: row(默认横排) | column(竖排) */
Grid — 复杂 Dashboard 布局
Grid 是二维布局方案,适合行+列同时需要的场景(比如 2×3 的看板):
.dashboard-grid {
display: grid;
grid-template-columns: repeat(3, 1fr); /* 3 列等宽 */
grid-template-rows: repeat(2, 1fr); /* 2 行等高 */
gap: 16px; /* 间距 */
}
/* 让某个卡片横跨 2 列 */
.card-wide {
grid-column: span 2;
}
常用 CSS 属性
| 属性 | 作用 | 示例 |
|---|---|---|
color | 文字颜色 | color: #333; |
background | 背景色/图 | background: #f5f7fa; |
font-size | 字体大小 | font-size: 16px; |
border-radius | 圆角 | border-radius: 8px; |
box-shadow | 阴影 | box-shadow: 0 2px 8px rgba(0,0,0,0.1); |
transition | 过渡动画 | transition: all 0.3s ease; |
opacity | 透明度 | opacity: 0.8; |
display | 显示方式 | display: flex / grid / none; |
position | 定位方式 | position: relative / absolute / fixed; |
一行或一列排列 → Flexbox(如导航栏、卡片列表)
行 + 列同时需要 → Grid(如整个 Dashboard 页面布局)
实际开发中两者经常混用:Grid 做大布局,Flex 做小组件内部排列。
03 · JavaScript ES6 — 大脑 / 肌肉
JavaScript = 网页的大脑,就像 Excel 里的 VBA 宏——让表格能动起来、能计算、能调接口。
没有 JS 的网页 = 只能看的 Excel 报表;有 JS 的网页 = 带宏的交互式看板。
let / const vs var
// ❌ var — 旧语法,有变量提升问题(容易出 bug)
var oee = 85;
// ✅ let — 可变变量(值可以改)
let oee = 85;
oee = 90; // OK,let 允许重新赋值
// ✅ const — 常量(值不能改)
const API_URL = '/api/oee';
// API_URL = '/api/abc'; // ❌ 报错!const 不能重新赋值
// 💡 经验法则:默认用 const,需要改的用 let,永远不用 var
箭头函数 () => {}
// 传统函数
function calcOee(a, p, q) {
return (a * p * q) / 10000;
}
// 箭头函数 — 更简洁
const calcOee = (a, p, q) => (a * p * q) / 10000;
// 只有一个参数时,括号可省略
const double = n => n * 2;
// 作为回调函数(非常常见)
data.filter(item => item.oee > 80);
data.map(item => item.name);
模板字符串 Template Literals
// ❌ 旧写法:字符串拼接(痛苦)
var msg = '设备 ' + name + ' OEE 为 ' + oee + '%';
// ✅ 模板字符串:用反引号 `` + ${变量}
const msg = `设备 ${name} OEE 为 ${oee}%`;
// 支持多行
const html = `
<div class="card">
<h3>${deviceName}</h3>
<p>OEE: ${oee}%</p>
</div>
`;
解构赋值 Destructuring
// 对象解构 — 从 API 返回的数据里取字段
const response = { availability: 92, performance: 91, quality: 99 };
// ❌ 传统写法
const a = response.availability;
const p = response.performance;
// ✅ 解构写法
const { availability, performance, quality } = response;
// 数组解构
const [first, second] = ['CNC-01', 'CNC-02'];
// 函数参数解构(非常常见)
const showDevice = ({ name, status, oee }) => {
return `${name}: ${status} (${oee}%)`;
};
展开运算符 Spread
// 合并数组
const shift1 = [120, 135, 110];
const shift2 = [140, 125];
const all = [...shift1, ...shift2]; // [120, 135, 110, 140, 125]
// 复制对象 + 修改某些字段
const defaults = { theme: 'dark', lang: 'zh', refresh: 30 };
const custom = { ...defaults, refresh: 10 }; // refresh 被覆盖为 10
Map / Filter / Reduce — 前端最重要的数组方法
| SQL | JavaScript | 作用 |
|---|---|---|
SELECT name FROM table | .map(item => item.name) | 提取/转换字段 |
WHERE oee > 80 | .filter(item => item.oee > 80) | 筛选符合条件的 |
SUM(output) | .reduce((sum, i) => sum + i.output, 0) | 汇总/聚合 |
// 模拟后端返回的设备数据
const devices = [
{ name: 'CNC-01', oee: 92, output: 1500 },
{ name: 'CNC-02', oee: 68, output: 980 },
{ name: 'CNC-03', oee: 85, output: 1320 },
{ name: 'CNC-04', oee: 55, output: 670 },
];
// 📌 filter — 找出 OEE > 80 的设备(相当于 WHERE oee > 80)
const goodDevices = devices.filter(d => d.oee > 80);
// → [{name:'CNC-01', ...}, {name:'CNC-03', ...}]
// 📌 map — 提取设备名称列表(相当于 SELECT name FROM ...)
const names = devices.map(d => d.name);
// → ['CNC-01', 'CNC-02', 'CNC-03', 'CNC-04']
// 📌 reduce — 汇总总产量(相当于 SUM(output))
const totalOutput = devices.reduce((sum, d) => sum + d.output, 0);
// → 4470
// 🔗 链式调用 — 找出 OEE > 80 的设备名称
const goodNames = devices
.filter(d => d.oee > 80)
.map(d => `${d.name} (${d.oee}%)`);
// → ['CNC-01 (92%)', 'CNC-03 (85%)']
Promise & async/await — 异步编程
同步 = 你站在机床前等加工完成,什么都干不了。
异步 = 你按下启动按钮后去做别的事,加工完了机床会通知你。
调用后端 API 就是异步的——请求发出后不会立刻得到结果,需要等待服务器响应。
// ❌ 回调地狱(旧写法,难以维护)
fetchOee(date, function(data) {
fetchDevices(data.lineId, function(devices) {
fetchAlerts(devices, function(alerts) {
// 嵌套3层了... 😵
});
});
});
// ✅ async/await(推荐写法,像写同步代码一样)
async function loadDashboard() {
try {
const oeeData = await fetchOee('2026-06-10'); // 等待 API 返回
const devices = await fetchDevices(oeeData.lineId);
const alerts = await fetchAlerts(devices);
renderDashboard(oeeData, devices, alerts);
} catch (err) {
showError(`加载失败: ${err.message}`);
}
}
// Promise 的三种状态:
// pending(进行中)→ fulfilled(成功)✅
// pending(进行中)→ rejected(失败)❌
Fetch API — 调用后端接口获取数据
// 📌 GET 请求 — 获取 OEE 数据
async function getOeeData() {
const response = await fetch('/api/oee?line=LINE-01');
const data = await response.json(); // 解析 JSON
return data;
}
// 📌 POST 请求 — 提交数据
async function updateDevice(id, params) {
const response = await fetch(`/api/devices/${id}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(params),
});
return await response.json();
}
// 📌 完整示例:加载并渲染 OEE 看板
async function loadOeeDashboard() {
try {
const data = await fetch('/api/oee');
if (!data.ok) throw new Error(`HTTP ${data.status}`);
const { availability, performance, quality } = await data.json();
const oee = (availability * performance * quality) / 10000;
// 更新 DOM
document.getElementById('oee-value').textContent = oee.toFixed(1) + '%';
} catch (err) {
console.error('OEE 加载失败:', err);
}
}
04 · DOM 操作
DOM = HTML 的「遥控器」。浏览器把 HTML 解析成一棵「DOM 树」,JS 通过 DOM API 来读取和修改页面上的任何元素。
类比 Excel VBA:Worksheets("Sheet1").Range("A1").Value = "Hello" 对应 document.getElementById('a1').textContent = 'Hello'
// 📌 选取元素
const el = document.getElementById('oee-card'); // 按 ID
const el2 = document.querySelector('.card .value'); // CSS 选择器(推荐)
const all = document.querySelectorAll('.card'); // 所有匹配项
// 📌 读取 / 修改内容
el.textContent = '85%'; // 纯文本
el.innerHTML = '<strong>85%</strong>'; // HTML 内容
el.value = 'CNC-01'; // 表单元素的值
// 📌 修改样式
el.style.color = 'red';
el.classList.add('active'); // 添加 class
el.classList.remove('hidden'); // 移除 class
el.classList.toggle('expanded'); // 切换 class
// 📌 创建新元素
const card = document.createElement('div');
card.className = 'card';
card.textContent = '新设备';
document.querySelector('.dashboard').appendChild(card);
// 📌 事件监听
const btn = document.querySelector('#refresh-btn');
btn.addEventListener('click', () => {
loadOeeDashboard(); // 点击刷新按钮 → 重新加载数据
});
| 操作 | 原生 DOM | jQuery | Excel VBA |
|---|---|---|---|
| 按 ID 选取 | getElementById('x') | $('#x') | Range("A1") |
| 改文本 | el.textContent = 'x' | $('#x').text('x') | Range("A1").Value = "x" |
| 改样式 | el.style.color = 'red' | $('#x').css('color','red') | Range("A1").Font.Color = RGB(255,0,0) |
| 点击事件 | el.addEventListener('click',fn) | $('#x').on('click',fn) | Button1_Click() |
在 Vue/React 项目中,你很少直接操作 DOM(框架帮你做了)。但在调试、写原生 JS、或理解框架底层时,DOM 知识仍然非常重要。
05 · 模块化 import / export
随着项目变大,把所有代码放在一个文件里就像把所有 Excel 数据放在一个 Sheet 里——混乱且难以维护。模块化 = 每个功能一个文件。
// api.js — 封装 API 调用
export async function getOeeData(line) {
const res = await fetch(`/api/oee?line=${line}`);
return res.json();
}
export const API_BASE = '/api/v1';
// main.js
import { getOeeData, API_BASE } from './api.js';
async function init() {
const data = await getOeeData('LINE-01');
renderChart(data);
}
init();
<!-- 注意 type="module" -->
<script type="module" src="./main.js"></script>
使用 import/export 时,<script> 必须加 type="module",否则浏览器不认识。
在 Vue/React 项目中,构建工具(Vite/Webpack)会自动处理模块化。
06 · 浏览器开发者工具
按 F12(Mac: Cmd+Option+I)打开开发者工具。这是前端工程师最重要的调试武器。
| 面板 | 用途 | 常用场景 |
|---|---|---|
| Elements | 查看/修改 HTML & CSS | 调样式、看元素结构、检查 class 是否生效 |
| Console | 执行 JS、查看日志 | console.log() 输出、报错信息、手动测试函数 |
| Network | 查看所有网络请求 | 调试 API 调用:请求参数对不对?返回什么数据?状态码? |
| Sources | 查看源代码 + 断点调试 | 设置断点、单步执行、查看变量值 |
| Application | 查看存储数据 | LocalStorage、SessionStorage、Cookie |
// 1. 在代码里加 log
async function loadData() {
console.log('🔵 开始加载数据...');
const res = await fetch('/api/oee');
console.log('🟢 响应状态:', res.status); // 200? 404? 500?
const data = await res.json();
console.log('🟡 返回数据:', data); // 看看实际返回了什么
console.table(data); // 表格形式展示数组
// 2. 去 Network 面板看:
// - 请求 URL 对不对?
// - Request Headers / Payload 对不对?
// - Response 是什么?
// - 耗时多久?(Timing)
}
F12 / Cmd+Option+I — 打开/关闭 DevTools
Cmd+Shift+C — 元素选择器(点页面上的元素跳到代码)
Cmd+Shift+M — 切换手机/PC 视图
console.log() — 最常用的调试手段,console.table() 用来展示数组数据特别方便
07 · 面试 Top 10 考点
语义化标签:<header> <nav> <main> <section> <article> <footer>,替代了满屏的 <div>,对 SEO 和可读性更友好。
表单增强:<input type="date/email/number/range">,自带校验和控件。
多媒体:<video> <audio> 不再需要 Flash。
Canvas / SVG:绘图能力,ECharts 等图表库的底层。
Web Storage:localStorage / sessionStorage 替代 Cookie 存本地数据。
优先级从高到低:!important > 行内 style > #id > .class / 属性 / 伪类 > 标签名 / 伪元素
计算方式:把选择器拆成 (行内数, ID数, class数, 标签数) 从左到右比较。
例:#dashboard .card p = (0, 1, 1, 1);.card .title = (0, 0, 2, 0)。前者优先级更高。
实践建议:尽量用 class 选择器,避免用 !important 和行内样式。
Flexbox = 一维布局(一行或一列)。适合导航栏、卡片列表、工具栏。
Grid = 二维布局(行 + 列同时控制)。适合整体页面布局、复杂看板。
实际项目:两者经常混用。Grid 做大框架,Flex 做小组件内部排列。
| 特性 | var | let | const |
|---|---|---|---|
| 作用域 | 函数作用域 | 块级作用域 | 块级作用域 |
| 变量提升 | ✅(易出 bug) | ❌ | ❌ |
| 重复声明 | ✅(静默覆盖) | ❌ 报错 | ❌ 报错 |
| 重新赋值 | ✅ | ✅ | ❌ |
结论:默认用 const,需要修改时用 let,永远不用 var。
== 会做类型转换再比较:'1' == 1 → true,0 == false → true
=== 严格比较,类型和值都必须相等:'1' === 1 → false
结论:永远用 ===,避免 == 的隐式转换带来的 bug。
pending(进行中)— 初始状态,异步操作还没完成
fulfilled(已成功)— 操作完成,.then() 里的回调会执行
rejected(已失败)— 操作失败,.catch() 里的回调会执行
状态一旦改变就不可逆(pending → fulfilled 或 pending → rejected,只能变一次)。
DOM 事件传播分三个阶段:
1. 捕获阶段:从 window → document → ... → 目标元素的父元素(从外到内)
2. 目标阶段:到达事件实际发生的元素
3. 冒泡阶段:从目标元素 → 父元素 → ... → window(从内到外)
默认监听的是冒泡阶段。可以用 e.stopPropagation() 阻止冒泡。
实际应用:事件委托——在父元素上监听,利用冒泡处理子元素事件,减少事件监听器数量。
最常用的(本教程已覆盖):
① let / const ② 箭头函数 => ③ 模板字符串 \`\${}\` ④ 解构赋值 ⑤ 展开运算符 ... ⑥ Map/Filter/Reduce ⑦ Promise + async/await ⑧ import/export 模块化
其他重要的:默认参数、for...of 循环、Set/Map 数据结构、Symbol、类 class 语法。
1. console.log() — 最简单,随时打印变量值。
2. 浏览器 DevTools — Console 面板看日志,Network 面板看 API 请求,Elements 面板看 DOM 结构。
3. 断点调试 — Sources 面板里设置断点,逐行执行,实时查看变量值。
4. Vue DevTools / React DevTools — 浏览器插件,专门调试框架组件。
5. Network 面板 — 检查 API 调用:URL、参数、返回数据、状态码、耗时。
SEO = Search Engine Optimization(搜索引擎优化),让网页在搜索结果中排名更靠前。
关键要点:
① 语义化 HTML:用 <h1> 表示标题、<nav> 表示导航、<article> 表示文章
② meta 标签:<title>、<meta name="description"> 告诉搜索引擎页面内容
③ 合理的 heading 层级:h1 > h2 > h3,不要跳级
④ 图片 alt 属性:<img alt="设备OEE看板"> 方便搜索引擎理解图片
⑤ 性能优化:页面加载速度也是排名因素
⑥ SSR(服务端渲染):对 SPA 应用(Vue/React),用 Nuxt/Next.js 做服务端渲染提升 SEO
08 · 速查表
前端三件套总结
| 技术 | 角色 | 类比 | Excel 对应 | 核心职责 |
|---|---|---|---|---|
| HTML | 骨架 | 人体骨骼 | Sheet 结构 | 定义页面有哪些内容 |
| CSS | 皮肤 | 衣服 + 化妆 | 单元格格式 | 定义页面长什么样 |
| JavaScript | 大脑 | 神经系统 | VBA 宏 | 定义页面的行为和逻辑 |
ES6 常用语法速查
| 语法 | 示例 | 用途 |
|---|---|---|
const / let | const API = '/api'; let count = 0; | 变量声明 |
| 箭头函数 | const add = (a, b) => a + b; | 简洁函数 |
| 模板字符串 | \`OEE: ${val}%\` | 字符串插值 |
| 解构 | const { name, oee } = device; | 提取对象/数组值 |
| 展开 | [...arr1, ...arr2] | 合并/复制 |
| filter | arr.filter(x => x > 80) | 筛选(= SQL WHERE) |
| map | arr.map(x => x.name) | 转换(= SQL SELECT) |
| reduce | arr.reduce((s,x) => s+x, 0) | 聚合(= SQL SUM) |
| async/await | const data = await fetch(url) | 异步调用 API |
| import/export | export fn; import { fn } | 模块化 |
CSS Flexbox 速查
| 属性 | 值 | 效果 |
|---|---|---|
display | flex | 开启 Flex 布局 |
flex-direction | row / column | 水平 / 垂直排列 |
justify-content | flex-start / center / space-between | 主轴对齐 |
align-items | stretch / center / flex-end | 交叉轴对齐 |
flex | 1 | 等分剩余空间 |
gap | 16px | 元素间距 |
第 1 周:HTML 标签 + CSS 基础(颜色、字体、盒模型)
第 2 周:Flexbox/Grid 布局 + CSS 常用属性
第 3 周:JavaScript ES6 基础(变量、函数、数组方法)
第 4 周:DOM 操作 + Fetch API + async/await
第 5 周起:进入 Vue 3 或 React 学习,将本教程知识应用到框架中