《Vue.js设计与实现》笔记

文章探讨了Vue.js3在框架定位、设计核心和设计思路方面的特点。它强调了声明式编程与过程关注的区别,如jQuery与原生JavaScript的DOM操作,以及Vue的模板系统。Vue.js3结合编译时和运行时的优势,优化了虚拟DOM更新性能。文章还提到,通过Tree-Shaking和条件编译来减小框架体积,提升开发体验并确保良好的错误处理。此外,介绍了渲染器和编译器的基本工作原理,以及组件的本质。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一章 框架的定位和方向

命令式声明式
差异关注过程,利用原生JavaScript 进行Dom操作(jQuery)关注结果,类 HTML 的模板(Vue)
优缺点理论上可以做到极致优化,但心智负担大封装了过程,损失一部分性能,心智负担小,可维护性更强
更新性能消耗直接修改找出差异(虚拟Dom) + 直接修改
纯运行时纯编译时
解释Render函数,将虚拟Dom -> 真实Dom。把 HTML 标签编译成树型结构的数据对象,或直接编译成命令式代码
缺点没办法分析用户提供的内容,哪些内容未来可能会改变,哪些内容永远不会改变由于不需要任何运行时,而是直接编译成可执行的 JavaScript 代码,因此性能可能会更好,但是这种做法有损灵活性

Vue.js 3 是一个编译时 + 运行时的声明式框架。

第二章 设计核心

开发体验是衡量一个框架的重要指标之一,提供友好的警告信息至关重要。提供了registerErrorHandler函数,用户可以使用它注册错误处理程序。

框架的大小也是衡量框架的标准之一。利用 Tree-Shaking 机制,定义__DEV__ 常量,生产环境去除警告信息。添加 /*#__PURE__*/ 注释,标记不会产生副作用的函数,辅助Tree-Shaking。定义__VUE_OPTIONS_API__常量等决定一些特性的开关,减少打包体积。

输出格式:

  1. IIFE 形式。立即执行的函数表达式,通过<script> 标签引入。
  2. ESM 格式。带有 -bundler 字样的 ESM 资源是给 rollup.js 或 webpack 等打包工具使用的,而带有 -browser 字样的 ESM 资源是直接给 <script type="module"> 使用的。前者需要(process.env.NODE_ENV !== ‘production’) 替换 __DEV__ 常量。
  3. cjs 格式。服务端渲染中,资源的模块格式应该是 CommonJS。

第三章 设计思路

介绍了编译器、渲染器的基本实现、组件的本质。

  1. 渲染器:虚拟Dom -> 真实Dom。
 // 虚拟Dom
 const vnode = {
     tag: "div",
     props: {
       onClick: () => alert("hello"),
     },
     children: "click me",
 };
 
 // 渲染器
 function renderer(vnode, container) {
     const el = document.createElement(vnode.tag);
     // 遍历 vnode.props,将属性、事件添加到 DOM 元素
     for (const key in vnode.props) {
       if (/^on/.test(key)) {
         el.addEventListener(
           key.substr(2).toLowerCase(), // onClick ---> click
           vnode.props[key] // 事件处理函数
         );
       }
     }
 
     // 处理 children
     if (typeof vnode.children === "string") {
       // 文本子节点
       el.appendChild(document.createTextNode(vnode.children));
     } else if (Array.isArray(vnode.children)) {
       // 递归地调用 renderer 函数渲染子节点,使用当前元素 el 作为挂载点
       vnode.children.forEach((child) => renderer(child, el));
     }
 
     container.appendChild(el);
 }
  1. 编译器:模板 -> 虚拟Dom。
const template = '<div id="foo" :class="cls"></div>';

// 虚拟Dom
 render() {
   return {
     tag: 'div',
     props: {
       id: 'foo',
       class: cls
     },
     patchFlags: 1 // 假设数字 1 代表 class 是动态的,通过标记知道哪些是动态的,提高性能
   }
 }
  1. 组件:DOM 元素的封装。
   const vnode = {
       tag: myComponent,
       props: {},
   };
   
   const myComponent = {
       tag: "div",
       props: {},
   }
   
   // 渲染器添加判断
   function renderer(vnode, container) {
     if (typeof vnode.tag === 'string') {
       mountElement(vnode, container)
     } else if (typeof vnode.tag === 'object') { // 如果是对象,说明 vnode 描述的是组件
       mountComponent(vnode, container)
     }
   }

更新中…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值