从刀耕火种到现代框架:DOM编程 vs Vue/React 进化史

从刀耕火种到现代框架:DOM编程 vs Vue/React 进化史

前端开发就像造房子:原生JS是手工砌砖,框架则是预制板建筑,效率提升100倍!

原生JS时代:刀耕火种的DOM编程

让我们回到"原始时代"的前端开发,那时的程序员像工匠一样手工操作每个DOM元素:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>原生JS</title>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
    <!--引入Bootstrap 3.3.6样式表实现响应式布局-->
</head>
<body>
    <!-- 挂载点 -->
     <div class="container">
   
     <table id="friends" class="table table-striped">
        <thead>
            <tr>
                <th>姓名</th>
                <th>家乡</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>小李</td>
                <td>抚州</td>
            </tr>
        </tbody>

     </table>
    </div>
    <script>
        //挂载点 这个位置的HTML由JS动态生成(html和js挂载的地方),表面这个地方的数据将会改变,是动态的
       // 通过document.querySelector()方法,基于CSS选择器规则,获取文档中ID为"friends"的表格元素下的tbody子元素,并将其引用赋值给常量oBody,以便后续操作表格内容。
        const oBody= document.querySelector('#friends tbody')
        //JSON 数组
        //DOM 编程 动态页面 
        //数据
        const friends = [
            {
                "name":"王子",
                "hometown":"九江"
            },
            {
                "name":"小美",
                "hometown":"赣州"
            }
        ]
        // html 字符串 = 数组 类型转换
        //使用数组的`map()`方法遍历`friends`数组
        // 为每个元素创建包含`<tr>`和两个`<td>`的 HTML 字符串
        //使用`join('')`将生成的字符串数组连接为一个完整的 HTML 片段
        //// `oBody.innerHTML = ...` 将片段插入 tbody,替换原有内容。
        oBody.innerHTML = friends.map(friend=>`
        <tr>
            <td>${friend.name}</td>
            <td>${friend.hometown}</td>
        </tr>
        `).join('')
    </script>
    
</body>
</html>

代码中一些关键的的解释

  1. script标签一般放于body的标签的最后

    • 可避免阻塞HTML渲染,让页面内容优先展示,减少白屏时间;
    • 确保脚本执行时DOM已加载完成,避免找不到元素的错误;
    • 还能优化资源并行加载,提升性能,是兼顾体验与效率的最佳实践。
  2. 挂载点: 挂载点是前端框架渲染的 DOM 容器,特点:

    1. 唯一性 :通过唯一 ID(如id="app")定位;
    2. 空容器:初始无内容,由框架动态填充;
    3. 专用性:仅用于框架挂载,不参与普通 DOM 操作。

    作用:作为视图渲染入口,连接虚拟 DOM 与真实 DOM,隔离框架逻辑与页面其他部分。

  3. 不用去写细节和重复代码 focus于业务 (熟)

    • 引入第三方库 booststrap PC css框架,业务类
    • .container容器 固定宽度
    • table标签

DOM编程的痛点 😫

  1. 繁琐的DOM操作:每个元素都要手动创建、插入、更新
  2. 数据与视图分离:数据变化时需要手动更新DOM
  3. 状态管理困难:随着应用复杂,状态分散在各处
  4. 性能问题:频繁操作DOM导致页面重绘

DOM操作就像在瓷器店里打棒球------稍有不慎就会搞砸整个页面!

现代框架的救赎:Vue/React的革命

为什么需要框架?

原生JS痛点 框架解决方案
DOM操作繁琐 声明式渲染
数据视图分离 数据驱动视图
状态管理混乱 组件状态管理
代码复用困难 组件化开发

Vue:渐进式框架的魅力

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>聚焦于业务,而不是底层API</title>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
    <!--引入 Bootstrap CSS 框架,提供响应式布局和样式(如表格条纹、容器居中),后续可以使用第三方库进行样式设计,`table table-striped`:为表格添加斑马条纹样式。 -->
</head>
<body>
    <div class="container" id="app">
    <!--`<div id="app">` 是 Vue 应用的挂载容器,Vue 将接管该元素内部的渲染。-->
        <h1>{{title}}</h1><!--双大括号是 Vue 的文本插值语法,用于显示动态数据。-->
        <table id="friends" class="table table-striped">
            <thead>
                <tr>
                    <th>姓名</th>
                    <th>家乡</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="friend in friends"><!--用于循环渲染列表数据-->
                    <td>{{ friend.name }}</td>
                    <td>{{ friend.hometown }}</td>
                </tr>
            </tbody>
        </table>  
    </div>
    <script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/3.2.31/vue.global.min.js"></script>
    <!--引入 Vue 3 的全局构建版本(CDN 链接),该版本将 Vue 挂载到全局作用域-->
    <script>
    // 做一个App 定义 Vue 应用的根组件,这是一个包含组件选项的对象
    const App = {
        // 申明数据的业务
        //组件的数据函数,必须返回一个对象
        // Vue 会将返回的对象转换为响应式数据
        data() {
            return {
                title:'ECUT 未来之星',
                friends: [
                    {
                        "name": "王子",
                        "hometown": "九江"
                    },
                    {
                        "name": "公主",
                        "hometown": "赣州"
                    },
                ]
            }
        }
    }
    // 挂载点
    // 使用 Vue 的 createApp 函数创建应用实例
    // 将 App 组件作为根组件传入
    //使用 mount 方法将应用挂载到 DOM 中 id 为 "app" 的元素上
    //这意味着页面中需要有一个<div id="app"></div>作为挂载点
    Vue.createApp(App).mount('#app')
    </script>
</body>
</html>
Vue的核心优势 ✨
  1. 响应式系统:数据变化自动更新视图
  2. 指令系统v-forv-if等简化逻辑
  3. 单文件组件:HTML/CSS/JS三位一体
  4. 渐进式架构:可按需引入功能

Vue就像贴心的管家------你只需要告诉它"我想要什么",它就会处理好所有细节!

React:函数式的力量

jsx 复制代码
function FriendsTable() {
  const [friends] = useState([
    { name: '王子', hometown: '九江' },
    { name: '公主', hometown: '赣州' }
  ]);

  return (
    <table>
      {friends.map(friend => (
        <tr key={friend.name}>
          <td>{friend.name}</td>
          <td>{friend.hometown}</td>
        </tr>
      ))}
    </table>
  );
}
React的独特之处 💡
  1. JSX语法:JavaScript和HTML的完美融合
  2. 虚拟DOM:高效更新界面
  3. 函数式组件:简洁的UI构建方式
  4. 强大的生态系统:Redux、React Router等配套工具

React就像乐高积木------用组件搭建出无限可能的UI世界!

框架的核心价值:聚焦业务逻辑

数据驱动视图的魔力

graph LR A[数据变化] --> B[框架检测变化] B --> C[计算最小更新] C --> D[更新真实DOM]

组件化:搭积木式开发

graph TB App --> Header App --> FriendList --> FriendItem App --> Footer

现代框架的三大支柱

  1. 声明式编程:描述"应该是什么",而不是"如何做"
  2. 组件化架构:高内聚、低耦合的代码组织
  3. 响应式系统:数据变化自动反映到UI

为什么说框架是必然选择?

  1. 开发效率提升:减少70%的DOM操作代码
  2. 代码可维护性:清晰的组件结构
  3. 性能优化:虚拟DOM减少重绘
  4. 团队协作:统一的设计模式
  5. 生态支持:路由、状态管理等解决方案

使用框架就像从自行车升级到高铁------同样的目的地,完全不同的体验!

真实案例:需求变更的应对

假设老板突然要求:

  1. 增加"年龄"列
  2. 添加筛选功能

原生JS方案:

  • 修改数据结构
  • 重写HTML拼接逻辑
  • 添加事件监听器
  • 手动更新表格

Vue/React方案:

js 复制代码
// Vue
{
  data() {
    return {
      // 1. 添加age字段
      friends: [
        { name: '...', hometown: '...', age: 20 }
      ],
      // 2. 添加过滤条件
      filter: ''
    }
  },
  computed: {
    // 3. 创建计算属性
    filteredFriends() {
      return this.friends.filter(f => 
        f.name.includes(this.filter))
    }
  }
}
jsx 复制代码
// React
function FriendList() {
  const [filter, setFilter] = useState('');
  const filteredFriends = friends.filter(f => 
    f.name.includes(filter));
  
  return (
    <>
      {/* 添加筛选输入框 */}
      <input onChange={e => setFilter(e.target.value)} />
      
      {filteredFriends.map(friend => (
        <tr>
          <td>{friend.name}</td>
          <td>{friend.hometown}</td>
          {/* 添加年龄列 */}
          <td>{friend.age}</td>
        </tr>
      ))}
    </>
  );
}
  1. friends.filter(...)
  • filter() 是数组的内置方法,遍历每个元素并返回一个新数组。

  • 新数组只包含 回调函数返回 true 的元素

  1. 回调函数 f => f.name.includes(filter)
  • f 是当前遍历的朋友对象(例如 { name: "王子", hometown: "九江" })。
  • f.name.includes(filter):检查 f.name 是否包含变量 filter 的值。
  • includes() 是字符串方法,返回 truefalse
  • filter 必须是一个已定义的变量(通常是用户输入的搜索词)。

结论:拥抱框架,聚焦业务

维度 原生JS Vue/React
开发速度 🐢 慢 🚀 快
代码量 📜 多 📄 少
可维护性 ❌ 差 ✅ 好
学习曲线 ⬇️ 平缓 ⬆️ 陡峭
适用场景 简单页面 复杂应用

前端开发箴言:

"不要重复造轮子,但要理解轮子的构造!"

学习框架的同时,不要忘记原生JS的基础。理解框架背后的原理,才能成为真正的高手!

最后的小测验:

当你下次看到document.querySelector()时,问问自己:

"这个操作真的必要吗?有没有更优雅的框架解决方案?" 💭

Happy coding! 🎉

相关推荐
Uyker2 分钟前
微信小程序动态效果实战指南:从悬浮云朵到丝滑列表加载
前端·微信小程序·小程序
小小小小宇27 分钟前
前端按需引入总结
前端
小小小小宇44 分钟前
React 的 DOM diff笔记
前端
小小小小宇1 小时前
react和vue DOM diff 简单对比
前端
我在北京coding1 小时前
6套bootstrap后台管理界面源码
前端·bootstrap·html
Carlos_sam1 小时前
Opnelayers:封装Popup
前端·javascript
前端小白从0开始2 小时前
Vue3项目实现WPS文件预览和内容回填功能
前端·javascript·vue.js·html5·wps·文档回填·文档在线预览
難釋懷2 小时前
Vue解决开发环境 Ajax 跨域问题
前端·vue.js·ajax
特立独行的猫a3 小时前
Nuxt.js 中的路由配置详解
开发语言·前端·javascript·路由·nuxt·nuxtjs