前言
1、Vue.js 目前最火的的一个前端框架,三大主流前端框架之一。
2、Vue.js 是一套构建用户界面的框架(一套完整的解决方案,对项目侵入性大,中途需要跟换框架则需要重构整个项目),只关注视图层,易上手,有配套的第三方类库。
3、提高开发效率,帮助减少不必要的 dom 操作;双向数据绑定,通过框架提供的指令,前端只需要关注业务逻辑,不再关心 dom 如何渲染。
跑个 demo
1 | <div id="counter">Counter: {{ counter }}</div>; |
旧版没有app
概念,3.0 引入新 API:createApp,调用 createApp 返回一个应用实例
2.x 全局 API | 3.x 实例 API (app) |
---|---|
Vue.config | app.config |
Vue.config.productionTip | 移除 |
Vue.config.ignoredElements | app.config.isCustomElement |
Vue.component | app.component |
Vue.directive | app.directive |
Vue.mixin | app.mixin |
Vue.use | app.use |
全局 API
1 | // 2.x |
createApp
返回一个提供应用上下文的应用实例。应用实例挂载的整个组件树共享同一个上下文。h
返回一个”虚拟节点“,通常缩写为 VNode:一个普通对象,其中包含向 Vue 描述它应在页面上渲染哪种节点的信息,包括所有子节点的描述defineComponent
创建一个组件defineAsyncComponent
创建一个只有在需要时才会加载的异步组件resolveComponent
返回一个 Component。如果没有找到,则返回 undefined。resolveDynamicComponent
返回已解析的 Component 或新创建的 VNode,其中组件名称作为节点标签。如果找不到 Component,将发出警告resolveDirective
返回一个 Directive。如果没有找到,则返回 undefined。withDirectives
允许将指令应用于 VNode。返回一个包含应用指令的 VNode。createRenderer
创建 rendernextTick
将回调推迟到下一个 DOM 更新周期之后执行
3.0 中全局 API 现在只能作为 ES 模块构建的命名导出进行访问,主要考虑到 tree-shaking
的支持。
应用 API
const app = createApp({}) 基于 app
component
注册或检索全局组件config
包含应用配置的对象directive
注册或检索全局指令mixin
在整个应用范围内应用混入mount
将应用实例的根组件挂载在提供的 DOM 元素上provide
设置一个可以被注入到应用范围内所有组件中的值, 组件应该使用 inject 来接收提供的值。unmount
在提供的 DOM 元素上卸载应用实例的根组件use
安装 Vue.js 插件
组件选项
1 | const vm = Vue.createApp({ |
生命周期
beforeCreate
在实例初始化之后created
在实例创建完成后被立即调用beforeMount
在挂载开始之前被调用mounted
实例被挂载后调用beforeUpdate
数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器updated
由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子activated
被 keep-alive 缓存的组件激活时调用deactivated
被 keep-alive 缓存的组件停用时调用beforeUnmount
在卸载组件实例之前调用。在这个阶段,实例仍然是完全正常的。unmounted
卸载组件实例后调用errorCaptured
当捕获一个来自子孙组件的错误时被调用renderTracked
跟踪虚拟 DOM 重新渲染时调用renderTriggered
当虚拟 DOM 重新渲染为 triggered.Similarly 为 renderTracked (此事件告诉你是什么操作触发了重新渲染,以及该操作的目标对象和键)
内置组件
新增组件 teleport,提供了一种干净的方法,允许我们控制在 DOM 中哪个父节点下呈现 HTML,而不必求助于全局状态或将其拆分为两个组件
- to - string。需要 prop,必须是有效的查询选择器或 HTMLElement (如果在浏览器环境中使用)。指定将在其中移动
内容的目标元素 - disabled - boolean。此可选属性可用于禁用
的功能,这意味着其插槽内容将不会移动到任何位置,而是在您在周围父组件中指定了 的位置渲染。
1 | <!-- 正确 --> |
核心- 响应式 Proxy
当把一个普通的 JavaScript 对象作为 data 选项传给应用或组件实例的时候,Vue 会使用带有 getter 和 setter 的处理程序遍历其所有 property 并将其转换为 Proxy。这是 ES6 仅有的特性,但是我们在 Vue 3 版本也使用了 Object.defineProperty
来支持 IE 浏览器。两者具有相同的 Surface API,但是 Proxy
版本更精简,同时提升了性能。
IE 支持程度:
Object.defineProperty IE9+ 详细兼容表
Proxy IE 不支持 Edge 支持 详细兼容表
核心二 组合式 API
vue2.x 都是基于 Class-API
,vue3.0 推荐 Composition-API
既 组合式 API
优点:
- 更好的逻辑复用与代码组织
- 更好的类型推导
1 | // 模版 |
以上是俩种使用方式的案例,使用组合式 API 的话所有逻辑是放着 setup 里面的,需要用到的生命周期钩子函数,监听 watch,computed 等都通过 import 方式导入
需要注意一个概念就是 setup 不属于 vue 构建的一个生命周期,他是一个组件选项,在创建组件之前执行,一旦 props 被解析,并作为组合式 API 的入口点
选项 API 生命周期选项和组合式 API 之间的映射
beforeCreate -> use setup()
created -> use setup()
beforeMount -> onBeforeMount
mounted -> onMounted
beforeUpdate -> onBeforeUpdate
updated -> onUpdated
beforeUnmount -> onBeforeUnmount
unmounted -> onUnmounted
errorCaptured -> onErrorCaptured
renderTracked -> onRenderTracked
renderTriggered -> onRenderTriggered
组合式 API 详解
- 响应性基础 API,reactive/ref
1 | import { reactive,ref } from 'vue'; |
- Computed
1 | import { ref, computed } from 'vue'; |
- watch/watchEffect
1 | import { ref, watchEffect, watch } from 'vue'; |
- Provide / Inject
1 | import { provide, inject } from 'vue'; |
- props/emit/slots/attrs
1 | export default { |
核心三 Virtual DOM
(虚拟 dom)
1.讨论虚拟 DOM 之前先了解一下真实 DOM 和其解析流程
不同浏览器的渲染引擎,可能有些差异,不过大流程差不多,大致分为 5 步:
- 1.创建 DOM 树: 用 HTML 分析器,分析 HTML 元素,构建一颗 DOM 树(标记化和树构建)
- 2.创建 StyleRules:用 CSS 分析器,分析 CSS 文件和元素上的 inline 样式,生成页面的样式表
- 3.创建 Render 树:将 DOM 树和样式表,关联起来,构建一颗 Render 树(这一过程又称为 Attachment)。每个 DOM 节点都有 attach 方法,接受样式信息,返回一个 render 对象(又名 renderer)。这些 render 对象最终会被构建成一颗 Render 树
- 4.布局 Layout:有了 Render 树,浏览器开始布局,为每个 Render 树上的节点确定一个在显示屏上出现的精确坐标
- 5.绘制 Painting:Render 树和节点显示坐标都有了,就调用每个节点 paint 方法,把它们绘制出来
2.Virtual DOM 可以看作是一个使用 javascript 模拟了 DOM 结构的树形结构,这个树结构包含整个 DOM 结构的信息
1 | <div id="app"> |
1 | { |
3.为什么要使用虚拟 DOM?
虚拟 DOM 就是为了解决浏览器性能问题而被设计出来的,频繁操作 dom 非常消耗性能,在整个前端项目中,浏览器的重绘和重排性能开销最大,因此尽量减少浏览器的重绘和重排是前端项目在做性能优化的时候的重点。
snabbdom.js
一个非常优秀的虚拟 dom 库,vue 的虚拟 dom 就参考这个
GitHub 地址
实现一个虚拟 DOM,需要如下三个步骤:
- compile, 我们如何能把真实的 DOM 编译成 Vnode。
- diff. 我们怎么样知道 oldVnode 和 newVnode 之间的不同。
- patch. 通过第二步的比较知道不同点,然后把不同的虚拟 DOM 渲染到真实的 DOM 上去