Web 前端零基础入门教程 — HTML/CSS/JavaScript + Vue/React

适用人群:零基础、想学前端开发的初学者
学习时长:约5-7天(每天4小时)
技术栈:HTML5 + CSS3 + JavaScript + Vue3/React
适用场景:网站开发、小程序、APP、管理后台

一、前端开发是什么?

前端开发负责用户在浏览器中看到和交互的一切:页面布局、样式美化、动态效果、数据交互。

技术作用类比
HTML页面结构房子的骨架
CSS页面样式房子的装修
JavaScript页面交互房子的电器开关
Vue/React开发框架精装修的样板间

二、HTML 基础(2小时入门)

2.1 基本结构

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>我的第一个网页</title>
</head>
<body>
    <h1>欢迎来到我的网站</h1>
    <p>这是一个段落。</p>
</body>
</html>

2.2 常用标签

<!-- 标题:h1最大,h6最小 -->
<h1>一级标题</h1>
<h2>二级标题</h2>
<h3>三级标题</h3>

<!-- 段落与文本 -->
<p>这是一个段落,<strong>粗体</strong>和<em>斜体</em>。</p>
<p>换行用<br>标签,水平线用<hr>标签。</p>

<!-- 链接 -->
<a href="https://www.bilibili.com" target="_blank">B站</a>

<!-- 图片 -->
<img src="photo.jpg" alt="照片描述" width="300">

<!-- 列表 -->
<ul>
    <li>无序列表项1</li>
    <li>无序列表项2</li>
</ul>

<ol>
    <li>有序列表项1</li>
    <li>有序列表项2</li>
</ol>

<!-- 表格 -->
<table border="1">
    <thead>
        <tr>
            <th>姓名</th>
            <th>年龄</th>
            <th>城市</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>张三</td>
            <td>25</td>
            <td>北京</td>
        </tr>
        <tr>
            <td>李四</td>
            <td>30</td>
            <td>上海</td>
        </tr>
    </tbody>
</table>

<!-- 表单 -->
<form action="/submit" method="POST">
    <div>
        <label for="name">姓名:</label>
        <input type="text" id="name" name="name" placeholder="请输入姓名" required>
    </div>
    <div>
        <label for="email">邮箱:</label>
        <input type="email" id="email" name="email" required>
    </div>
    <div>
        <label for="password">密码:</label>
        <input type="password" id="password" name="password" minlength="6">
    </div>
    <div>
        <label>性别:</label>
        <input type="radio" name="gender" value="male" id="male">
        <label for="male">男</label>
        <input type="radio" name="gender" value="female" id="female">
        <label for="female">女</label>
    </div>
    <div>
        <label for="city">城市:</label>
        <select id="city" name="city">
            <option value="">请选择</option>
            <option value="beijing">北京</option>
            <option value="shanghai">上海</option>
            <option value="guangzhou">广州</option>
        </select>
    </div>
    <div>
        <label for="bio">简介:</label>
        <textarea id="bio" name="bio" rows="4"></textarea>
    </div>
    <button type="submit">提交</button>
</form>

<!-- 语义化标签 -->
<header>页面头部</header>
<nav>导航栏</nav>
<main>主要内容</main>
<section>内容区块</section>
<article>文章</article>
<aside>侧边栏</aside>
<footer>页脚</footer>


三、CSS 基础(3小时入门)

3.1 选择器

/* 元素选择器 */
h1 { color: #333; }

/* 类选择器 */
.highlight { background: yellow; }

/* ID选择器 */
#header { height: 60px; }

/* 后代选择器 */
.nav a { color: white; }

/* 子元素选择器 */
.nav > li { display: inline-block; }

/* 伪类选择器 */
a:hover { color: red; }
input:focus { border-color: blue; }

/* 伪元素选择器 */
.quote::before { content: """; }
.quote::after { content: """; }

3.2 盒模型

/* 盒模型 = content + padding + border + margin */
.box {
    width: 300px;           /* 内容宽度 */
    height: 200px;          /* 内容高度 */
    padding: 20px;          /* 内边距 */
    border: 2px solid #ccc; /* 边框 */
    margin: 10px;           /* 外边距 */
    
    /* 推荐:让width/height包含padding和border */
    box-sizing: border-box;
}

3.3 Flexbox 布局(最常用)

/* 父容器设置 */
.container {
    display: flex;
    
    /* 主轴方向:row(默认) | column */
    flex-direction: row;
    
    /* 主轴对齐:flex-start | center | flex-end | space-between | space-around */
    justify-content: space-between;
    
    /* 交叉轴对齐:flex-start | center | flex-end | stretch */
    align-items: center;
    
    /* 是否换行:nowrap(默认) | wrap */
    flex-wrap: wrap;
    
    /* 间距 */
    gap: 20px;
}

/* 子元素设置 */
.item {
    /* 放大比例:0不放大,1平分剩余空间 */
    flex-grow: 1;
    
    /* 缩小比例:0不缩小 */
    flex-shrink: 0;
    
    /* 初始大小 */
    flex-basis: 200px;
    
    /* 简写:放大 缩小 初始大小 */
    flex: 1 0 200px;
}

/* 常见布局 */
/* 水平居中 */
.center-h { display: flex; justify-content: center; }

/* 垂直居中 */
.center-v { display: flex; align-items: center; }

/* 完全居中 */
.center { display: flex; justify-content: center; align-items: center; }

/* 两端对齐 */
.between { display: flex; justify-content: space-between; }

3.4 Grid 布局

.grid-container {
    display: grid;
    
    /* 定义列:3列等宽 */
    grid-template-columns: repeat(3, 1fr);
    
    /* 或者:固定宽度 */
    grid-template-columns: 200px 1fr 200px;
    
    /* 定义行 */
    grid-template-rows: auto;
    
    /* 间距 */
    gap: 20px;
}

/* 子元素跨列 */
.item-wide {
    grid-column: 1 / 3;  /* 从第1列到第3列 */
}

/* 响应式网格 */
@media (max-width: 768px) {
    .grid-container {
        grid-template-columns: 1fr;  /* 手机上单列 */
    }
}

3.5 响应式设计

/* 移动优先原则:先写手机样式,再适配大屏幕 */

/* 手机(默认) */
.container { padding: 10px; }
.nav { display: none; }

/* 平板(768px+) */
@media (min-width: 768px) {
    .container { padding: 20px; }
    .nav { display: flex; }
}

/* 桌面(1024px+) */
@media (min-width: 1024px) {
    .container { max-width: 1200px; margin: 0 auto; }
}

/* 常用断点 */
/* 576px  - 手机横屏 */
/* 768px  - 平板 */
/* 1024px - 小桌面 */
/* 1200px - 大桌面 */
/* 1400px - 超大桌面 */


四、JavaScript 基础(5小时入门)

4.1 基本语法

// ====================
// 1. 变量声明
// ====================
let name = "张三";       // 可变变量
const age = 25;          // 不可变常量
var old = "不推荐用var";  // 旧语法,避免使用

// ====================
// 2. 数据类型
// ====================
let str = "Hello";       // 字符串
let num = 42;            // 数字
let bool = true;         // 布尔
let arr = [1, 2, 3];     // 数组
let obj = { name: "张三", age: 25 };  // 对象
let nothing = null;      // 空值
let undef = undefined;   // 未定义

// ====================
// 3. 字符串模板(反引号)
// ====================
let greeting = `你好,${name}!今年${age}岁。`;

// ====================
// 4. 箭头函数
// ====================
const add = (a, b) => a + b;
const greet = (name) => {
    return `你好,${name}!`;
};

// ====================
// 5. 解构赋值
// ====================
// 数组解构
const [first, second] = [1, 2, 3];  // first=1, second=2

// 对象解构
const { username, email } = { username: "张三", email: "test@example.com" };

4.2 数组操作(高频使用)

const users = [
    { name: "张三", age: 25, city: "北京" },
    { name: "李四", age: 30, city: "上海" },
    { name: "王五", age: 28, city: "北京" },
    { name: "赵六", age: 22, city: "广州" }
];

// map:转换每个元素
const names = users.map(u => u.name);  // ["张三", "李四", "王五", "赵六"]

// filter:过滤元素
const beijingUsers = users.filter(u => u.city === "北京");

// find:找到第一个匹配的
const user = users.find(u => u.name === "张三");

// reduce:聚合计算
const totalAge = users.reduce((sum, u) => sum + u.age, 0);

// some/every:条件判断
const hasYoung = users.some(u => u.age < 25);    // true
const allAdult = users.every(u => u.age >= 18);   // true

// sort:排序
const sorted = [...users].sort((a, b) => a.age - b.age);

// 链式调用
const result = users
    .filter(u => u.city === "北京")
    .map(u => u.name)
    .join("、");  // "张三、王五"

4.3 异步编程(async/await)

// ====================
// Promise 基础
// ====================
const fetchUser = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve({ name: "张三", age: 25 });
        }, 1000);
    });
};

// ====================
// async/await(推荐写法)
// ====================
async function getUser() {
    try {
        const user = await fetchUser();
        console.log(user);
    } catch (error) {
        console.error("获取用户失败:", error);
    }
}

// ====================
// Fetch API(网络请求)
// ====================
// GET 请求
async function getUsers() {
    const response = await fetch('/api/users');
    const data = await response.json();
    return data;
}

// POST 请求
async function createUser(userData) {
    const response = await fetch('/api/users', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(userData)
    });
    return await response.json();
}

// ====================
// Axios(更方便的HTTP库)
// ====================
// npm install axios
import axios from 'axios';

const api = axios.create({ baseURL: '/api' });

// GET
const { data: users } = await api.get('/users');

// POST
const { data: newUser } = await api.post('/users', {
    username: '张三',
    email: 'test@example.com'
});

4.4 DOM 操作

// 获取元素
const btn = document.getElementById('myBtn');
const items = document.querySelectorAll('.item');
const first = document.querySelector('.item');

// 修改内容
btn.textContent = '点击我';
btn.innerHTML = '<strong>加粗文字</strong>';

// 修改样式
btn.style.color = 'red';
btn.style.backgroundColor = '#f0f0f0';
btn.classList.add('active');
btn.classList.remove('disabled');
btn.classList.toggle('visible');

// 事件监听
btn.addEventListener('click', () => {
    alert('按钮被点击了!');
});

// 表单处理
const form = document.getElementById('myForm');
form.addEventListener('submit', (e) => {
    e.preventDefault();
    const formData = new FormData(form);
    const data = Object.fromEntries(formData);
    console.log(data);
});

// 创建元素
const div = document.createElement('div');
div.textContent = '新元素';
div.className = 'new-item';
document.body.appendChild(div);


五、Vue 3 入门(最推荐的前端框架)

5.1 为什么选 Vue?

对比项Vue 3ReactAngular
学习曲线★★☆☆☆★★★☆☆★★★★☆
中文文档极好一般一般
国内就业主流主流较少
体积大小
适用场景中小项目、管理后台大型项目企业级项目

5.2 Vue 3 核心概念

<!-- App.vue -->
<template>
  <div class="app">
    <h1>{{ title }}</h1>
    
    <!-- 双向绑定 -->
    <input v-model="inputText" placeholder="输入内容">
    <p>你输入了:{{ inputText }}</p>
    
    <!-- 条件渲染 -->
    <p v-if="isLoggedIn">欢迎回来,{{ username }}</p>
    <p v-else>请先登录</p>
    
    <!-- 列表渲染 -->
    <ul>
      <li v-for="user in users" :key="user.id">
        {{ user.name }} - {{ user.email }}
      </li>
    </ul>
    
    <!-- 事件处理 -->
    <button @click="addUser">添加用户</button>
    <button @click="count++">点击次数:{{ count }}</button>
    
    <!-- 计算属性 -->
    <p>用户总数:{{ userCount }}</p>
    <p>筛选结果:{{ filteredUsers.length }} 人</p>
  </div>
</template>

<script setup>
import { ref, computed, reactive } from 'vue'

// 响应式数据
const title = ref('Vue 3 入门')
const count = ref(0)
const inputText = ref('')
const isLoggedIn = ref(false)
const username = ref('张三')

// 响应式对象
const users = reactive([
  { id: 1, name: '张三', email: 'zhangsan@example.com' },
  { id: 2, name: '李四', email: 'lisi@example.com' }
])

// 计算属性
const userCount = computed(() => users.length)
const filteredUsers = computed(() => 
  users.filter(u => u.name.includes(inputText.value))
)

// 方法
const addUser = () => {
  users.push({
    id: Date.now(),
    name: '新用户',
    email: 'new@example.com'
  })
}
</script>

<style scoped>
.app { max-width: 800px; margin: 0 auto; padding: 20px; }
button { margin: 5px; padding: 8px 16px; cursor: pointer; }
</style>

5.3 组件通信

<!-- 父组件 Parent.vue -->
<template>
  <ChildComponent 
    :title="parentTitle"
    @update="handleUpdate"
  />
</template>

<script setup>
import { ref } from 'vue'
import ChildComponent from './ChildComponent.vue'

const parentTitle = ref('来自父组件的数据')

const handleUpdate = (newData) => {
  console.log('子组件传来的数据:', newData)
}
</script>

<!-- 子组件 ChildComponent.vue -->
<template>
  <div>
    <h2>{{ title }}</h2>
    <button @click="sendToParent">通知父组件</button>
  </div>
</template>

<script setup>
// 接收props
const props = defineProps({
  title: { type: String, default: '' }
})

// 发送事件
const emit = defineEmits(['update'])

const sendToParent = () => {
  emit('update', { message: '来自子组件' })
}
</script>

5.4 Vue Router 路由

// router/index.js
import { createRouter, createWebHistory } from 'vue-router'

const routes = [
  { path: '/', component: () => import('../views/Home.vue') },
  { path: '/about', component: () => import('../views/About.vue') },
  { 
    path: '/user/:id', 
    component: () => import('../views/User.vue'),
    props: true  // 将路由参数作为props传递
  },
  {
    path: '/admin',
    component: () => import('../views/Admin.vue'),
    meta: { requiresAuth: true },  // 需要登录
    children: [
      { path: 'users', component: () => import('../views/admin/Users.vue') },
      { path: 'posts', component: () => import('../views/admin/Posts.vue') }
    ]
  }
]

const router = createRouter({
  history: createWebHistory(),
  routes
})

// 路由守卫
router.beforeEach((to, from, next) => {
  if (to.meta.requiresAuth && !isAuthenticated()) {
    next('/login')
  } else {
    next()
  }
})

export default router

5.5 Pinia 状态管理

// stores/user.js
import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
  state: () => ({
    userInfo: null,
    token: localStorage.getItem('token') || ''
  }),
  
  getters: {
    isLoggedIn: (state) => !!state.token,
    displayName: (state) => state.userInfo?.nickname || state.userInfo?.username || ''
  },
  
  actions: {
    async login(credentials) {
      const { data } = await api.post('/auth/login', credentials)
      this.token = data.token
      this.userInfo = data.user
      localStorage.setItem('token', data.token)
    },
    
    async fetchUser() {
      const { data } = await api.get('/user')
      this.userInfo = data
    },
    
    logout() {
      this.token = ''
      this.userInfo = null
      localStorage.removeItem('token')
    }
  }
})

// 在组件中使用
// const userStore = useUserStore()
// userStore.login({ username, password })
// userStore.isLoggedIn


六、React 入门(另一个主流框架)

6.1 React 核心概念

// App.jsx
import { useState, useEffect, useMemo } from 'react'

function App() {
  // 状态管理
  const [count, setCount] = useState(0)
  const [users, setUsers] = useState([])
  const [keyword, setKeyword] = useState('')

  // 副作用(类似Vue的onMounted)
  useEffect(() => {
    fetchUsers()
  }, [])

  // 计算属性
  const filteredUsers = useMemo(() => 
    users.filter(u => u.name.includes(keyword)),
    [users, keyword]
  )

  const fetchUsers = async () => {
    const res = await fetch('/api/users')
    const data = await res.json()
    setUsers(data)
  }

  return (
    <div className="app">
      <h1>用户管理</h1>
      
      <input 
        value={keyword}
        onChange={e => setKeyword(e.target.value)}
        placeholder="搜索用户"
      />
      
      <p>共 {filteredUsers.length} 个用户</p>
      
      <ul>
        {filteredUsers.map(user => (
          <li key={user.id}>{user.name} - {user.email}</li>
        ))}
      </ul>
      
      <button onClick={() => setCount(count + 1)}>
        点击次数:{count}
      </button>
    </div>
  )
}

export default App

6.2 React 组件

// UserCard.jsx
function UserCard({ user, onDelete }) {
  return (
    <div className="user-card">
      <h3>{user.name}</h3>
      <p>{user.email}</p>
      <button onClick={() => onDelete(user.id)}>删除</button>
    </div>
  )
}

// 父组件使用
function UserList() {
  const [users, setUsers] = useState([])
  
  const handleDelete = (id) => {
    setUsers(users.filter(u => u.id !== id))
  }
  
  return (
    <div>
      {users.map(user => (
        <UserCard key={user.id} user={user} onDelete={handleDelete} />
      ))}
    </div>
  )
}


七、Vue vs React 选择建议

场景推荐原因
零基础入门Vue中文文档好,学习曲线平缓
管理后台VueElement Plus 生态完善
小程序/APPVue (uni-app)跨端方案成熟
大型项目React社区更大,方案更多
海外就业React全球市场主流
国内就业Vue/React 都学两个都要会

八、前端工程化

8.1 包管理器

# npm(Node.js自带)
npm install axios
npm install -D vite
npm run dev

# pnpm(推荐,更快更省空间)
npm install -g pnpm
pnpm add axios
pnpm add -D vite
pnpm dev

8.2 Vite 项目创建

# 创建Vue项目
npm create vite@latest my-vue-app -- --template vue

# 创建React项目
npm create vite@latest my-react-app -- --template react

# 进入项目并启动
cd my-vue-app
npm install
npm run dev


学习建议

  1. 先学HTML+CSS,能写出静态页面建立信心
  2. 再学JavaScript基础,重点掌握数组操作和async/await
  3. 选择Vue或React深入学习,建议先学Vue(中文友好)
  4. 做一个完整项目(Todo应用或个人博客)巩固所学
  5. 学习工程化工具:Vite、npm/pnpm、Git

下一步学习

返回首页