1. Vue 3.0介绍

news2024/11/26 16:55:51

Vue3.0介绍

1.Vue.js 3.0 源码组织方式

Vue2.x与Vue3.0的区别

  • 源码组织方式的变化

    • Vue3.0的源码全部采用TypeScript重写
    • 使用Monorepo方式来组织项目结构,把独立的功能模块都提取到不同的包中。

    packages下都是独立发行的包,可以独立使用。

  • Composition API(组合API)

    Vue 3.0代码虽然重写,但是90%以上的API兼容2.x,并且增加了Composition API(组合API),是用来解决Vue 2.x在开发大型项目时遇到超大组件,使用options API不好拆分和重用的问题。

  • 性能提升

    Vue 3.0使用Proxy重写了响应式代码,并对编译器做了优化,重写了虚拟DOM,从而让渲染和update的性能都有了大幅度的提升,另外服务端渲染SSR的性能也提升了2-3倍。

  • Vite

    官方提供了一个开发工具Vite,使用Vite在开发和测试阶段,不用打包项目,可以直接去运行项目,提升了开发的效率。

2.不同的构建版本

3.Composition API 设计动机

  • RFC (Request For Comments)

    https://github.com/vuejs/rfcs

  • Composition API RFC

    https://composition-api.vuejs.org

Composition API 的设计动机

Options API:使用包含组件描述选项的对象来创建组件的方式。例如选项:datamethodscreated等等组成对象,来组成组件。

案例:可以看到要实现一个功能,需要在不同选项中添加。如果此时需要在添加一个功能,就需要在多个选项中添加代码。并且难以提取组件中重复的代码。

  • Options API(Vue 2.x)

    • 包含一个描述组件选项(data、methods、props等)的对象
    • Options API开发复杂组件,同一个功能逻辑的代码被拆分到不同选项
    • Options API难以提取组件中可重用的逻辑,虽然有mixin,但容易命名冲突,数据来源不清晰。
  • Composition API(Vue 3.0)

    • Vue 3.0新增的一组API
    • 一组基于函数的API
    • 可以更灵活的组织组件的逻辑

    Compisition API案例,可以看到将功能封装到一个函数内部,如果需要再增加一个功能,只需要再封装一个函数,然后在setup函数中调用函数。

官方提供的案例图,Options API中可以看到相同色块代表同一个功能,分布在不同的位置,而Composition API则是一个功能一个块。

4.性能提升

  • 响应式系统升级

    首先来看一下响应式系统升级。我们都知道Vue2的时候,数据响应式的原理使用的是defineProperty,在初始化的时候会遍历data中的所有成员。通过defineProperty,把对象的属性转换成gettersetter。如果data中的属性又是对象的话,需要递归处理每一个子对象的属性。注意这些都是在初始化的时候进行的。也就是说如果你没有使用这个属性的时候,你也把它进行了响应式的处理。

    而Vue3中采用的是ES6以后新增的proxy对象。proxy对象的性能本身就比defineProperty要好。另外,代理对象可以拦截属性的访问、复制、删除等操作。不需要初始化的时候遍历所有的属性。另外,如果有多层属性嵌套的话,只有访问某个属性的时候,才会递归处理下一级的属性,使用proxy对象默认就可以监听到动态添加的属性。而Vue2里边想要动态添加一个显示的属性需要调用this.$set的方法来处理。而且Vue2中还监听不到属性的删除,对数组的索引和length属性的修改也监听不到。Vue3中使用代理对象可以监听属性的删除以及数组的索引和length属性的修改操作。所以Vue3中使用proxy对象提升了响应式系统的性能和功能。

    • Vue 2.x中响应式系统的核心是defineProperty
    • Vue 3.0中使用Proxy对象重写响应式系统
      • 可以监听动态新增的属性
      • 可以监听删除的属性
      • 可以监听数组的索引和length属性
  • 编译优化

    Vue3中通过优化编译的过程和重写虚拟DOM,让首次渲染和更新的性能有了大幅度的提升。我们知道Vue2的时候,模板首先需要编译成render函数,这个过程一般是在构建的过程中完成的。在编译的时候会编译静态根节点静态节点。静态根节点要求节点中必须有一个静态子节点,当组件的状态发生变化后,会通知watch触发watcherupdate。最终去执行虚拟DOMpatch操作遍历所有的虚拟节点,找到差异,然后更新到真实DOM上。
    Diff的过程中会去比较整个虚拟DOM,先对比新旧的div以及它的属性,然后再对比它内部的子节点。Vue2中渲染的最小单位是组件。Vue2中diff的过程会跳过静态根节点,因为静态根节点的内容不会发生变化,也就是Vue2中通过标记静态根节点优化了diff的过程。但是在Vue2的时候,静态节点还需要再进行diff,这个过程没有被优化

    Vue3中为了提高性能,在编译的时候会标记和提升所有的静态节点,然后diff的时候只需要对比动态节点的内容。另外在Vue3中新引入了一个Fragments,也就是片段的特性,模板中不需要再创建一个唯一的根节点模板,里边可以直接放文本内容或者很多同级的标签。

    在Vs code中需要升级你的Vetur插件,否则模板中如果没有唯一的根据点VS Code依然会提示有错误。

    左边是我们刚刚看到的组件模板中的内容,右边是我们编译之后的render函数,但是这个编译的结果跟Vue2会有很大的区别,首先这里调用_createBlock给我们的根div创建了一个block,它是一个树的结构,然后通过createVNode的去创建了我们的子节点,那这里的createVNode的其实就是类似于我们之前的h函数。

    那我们来删除这里面的根节点,来看一下它的变化。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DRUSTVaP-1669553000301)(C:/Users/5coder/AppData/Roaming/Typora/typora-user-images/image-20221126161031253.png)]当我们删除根节点之后,这里会创建一个fragment,也就是我们之前说的片段。其实从这里还可以看到,它内部还是维护了一个树形的结构,那么最外层是fragment,里边是我们的这些VNode的。
    Vue 2.x中通过标记静态根节点,优化diff的过程

    • Vue 3.0中标记和提升所有的静态根节点,diff的时候只需要对比动态节点内容
      • Fragments(升级vetur插件)
      • 静态提升
      • Patch flag
      • 缓存事件处理函数
  • 源码体积的优化

    • Vue 3.0中移除了一些不常用的API(如inline-template、filter等)
    • Tree-shaking

5.Vite

ES Module

  • 现代浏览器都支持ES Module(IE不支持)
  • 通过下面的方式加载模块
  • 支持模块的script默认延迟加载(相当于省略了defer属性)
    • 类似于script标签设置defer
    • 在文档解析完成后,触发DOMContentLoaded事件前执行(加载模块并执行,是在DOM创建之后,并且在DOMContentLoaded执行之前执行的)

浏览器使用ES Module案例

项目结构:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="app">Hello World</div>
  <script>
    window.addEventListener('DOMContentLoaded', () => {
      console.log('DOMContentLoaded')
    })

  </script>
  <script type="module" src="./modules/index.js"></script>
</body>
</html>

modules/index.js

import { forEach } from './utils.js'

const app = document.querySelector('#app')
console.log(app.innerHTML)

const arr = [1, 2, 3]
forEach(arr, item => {
  console.log(item)
})

modules/utils.js

export const forEach = (array, fn) => {
  let i
  for (i = 0; i < array.length; i++) {
    fn(array[i])
  }
}

export const some = (array, fn) => {
  let result = true
  for (const value of array) {
    result = result || fn(value)
    if (result) {
      break
    }
  }
  return result
}

打开index.html我们可以发现,设置了type="module"后,script默认延迟加。并且执行结果为:先加载模块,后执行DomContentLoaded事件。

Vite与Vue-cli区别

Vite的快就是使用浏览器支持的ES module的方式,避免开发环境下打包,从而提升开发速度。下面看一下ViteVue Cli的区别,最主要的区别是Vite在开发环境下不需要打包,因为在开发模式下,Vite使用浏览器原生支持的ES module加载模块,也就是通过import来导入模块,支持ES module的现代浏览器通过script type="module"的方式加载模块代码。

因为Vite不需要打包项目,因此Vite在开发模式下打开页面是秒开的,而Vue Cli在开发环境下会先打包整个项目,如果项目比较大,速度会特别慢。

  • Vite在开发模式下不需要打包可以直接运行
  • Vue-cli开发模式下必须对项目打包才可以运行
  • Vite在生产环境下使用Rollup打包基于ES Module的方式打包
  • Vue-cli使用webpack打包

Vite特点

Vite会开启一个测试的服务器,它会拦截浏览器发送的请求,浏览器会向服务器发送请求获取相应的模块,那为此会对浏览器不识别的模块进行处理。比如当import单文件组件的时候,也就是后缀名为.vue的文件时,会在服务器上对.vue文件进行编译,把编译的结果返回给浏览器。稍后我们会演示这个过程。使用这种方式让Vite有以下的优点:

  • 快速冷启动

    因为不需要打包,所以可以快速冷启动。

  • 按需编译

    代码是按需编译的,因此只有当代码在当前需要加载的时候才会编译。你不需要在开启开发服务器的时候等待整个项目被打包,那当项目比较大的时候,这个时候就会更明显。

  • 模块热更新

    Vite支持模块热更新,并且模块热更新的性能与模块总数无关。无论你有多少模块,HMR的速度始终比较快。

另外,Vite在生产环境下使用Rollup打包,Rollup基于浏览器原生的ES Module进行打包,它不需要再使用Babel,再把import转换成require以及一些相应的辅助函数,因此打包的体积会比webpack打包的体积更小。现在浏览器都已经支持ES Module的方式加载模块。

Vite创建项目

Vite有两种创建项目的方式,一种是创建基于Vue3的项目,可以直接在终端输入npm init vite-app <项目名称>来创建项目,然后再切换到项目目录cd <项目名称>,输入npm i安装依赖。最后通过npm run dev在开发环境下运行项目。

还有一种方式是基于模板创建项目,Vite基于模板的方式可以让它支持其他的框架,在创建项目的时候,后面跟上要使用的框架,比如是--template react

这里我们演示第一种方式。

使用第一种方式创建后的项目目录结构如下:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <link rel="icon" href="/favicon.ico" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vite App</title>
</head>
<body>
  <div id="app"></div>
  <script type="module" src="/src/main.js"></script>
</body>
</html>

main.js

import { createApp } from 'vue'
import App from './App.vue'  // 将单文件组件当成模块来加载
import './index.css'

createApp(App).mount('#app')

APP.vue

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <HelloWorld msg="Hello Vue 3.0 + Vite" />
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}
</script>

使用npm run dev运行项目,可以开发服务器开启的速度很快,因为他没有打包的过程。

网页源代码:

打开开发人员工具,找到NetWork

这里有很多请求,找一下.vue结尾的这块有一个app.vue。Vite开启的这个web服务器,它会劫持.vue的请求,它首先会把.vue文件解析成JS文件,并且把响应头中的contentType设置为application/javascript,目的是告诉浏览器我现在给你发送的是一个javascript脚本

那下面我们再来看response,这是服务器解析的js模块,这里又导入了helloWorld.vue这个单文件组件。

注意import { render as __render } from "/src/App.vue?type=template"。这里又通过import导入了App.vue模块,后面加了一个参数:type="template"。这里导入这个模块的render函数,注意,我们的App.vue是单文件组件,在编写的时候根本没有写render函数。现在之所以能导出这个render函数,是因为服务器对它做了特殊的处理,我们一会儿来解释。那这里只要加载模块就会向服务器发送请求,请求这个模块。

再来往下看,这里又请求了HelloWorld.vue这个单文件组件,它的处理方式跟刚刚的App.vue是一样的。再往下看的话,这里又请求了App.vue?type=template。这次请求到服务器之后,服务器会把这个App.vue这个单文件组件通过vue中的模块compile-sfc给它编译成render函数。

可以看到response中的内容,这里首先把静态节点提升,然后下面是render函数。这就是Vite的工作原理:它使用浏览器支持的ES Module的方式来加载模块。在开发环境下,它不会打包项目,把所有的模块的请求都交给服务器来处理,在服务器去处理浏览器不能识别的模块。如果是单文件组件,会调用compile-sfc编译单文件组件,并把编译的结果返回给浏览器。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/42537.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[U3D ShaderGraph] 全面学习ShaderGraph节点 | 第二课 | Input/Geometry

ShaderGraph是可视化的着色器编辑工具。您可以使用此工具以可视方式创建着色器。 本专栏可以让你更了解ShaderGraph中每个节点的功能&#xff0c;更自如的在做出自己想要的效果。 如果你想学习在unity中如何制作一个特效&#xff0c;如何在unity中让模型更炫酷&#xff0c;那就…

Python实现导弹自动追踪

自动追踪算法&#xff0c;在我们制作射击类游戏时经常会用到。这个听起来很高大上的东西&#xff0c;其实并不是军事学的专利&#xff0c;从数学上来说就是解微分方程。 这个没有点数学基础是很难算出来的。但是我们有了计算机就不一样了&#xff0c;依靠计算机极快速的运算速…

【Scala专栏】走进Scala

官方文档: https://www.scala-lang.org/ 一、What is Scala? Scala是一种针对JVM 将面向函数和面向对象技术组合在一起的编程语言。Scala编程语言近来抓住了很多开发者的眼球。它看起来像是一种纯粹的面向对象编程语言&#xff0c;而又无缝地结合了命令式和函数式的编程风格…

服务访问质量(QoS)——流量整形与拥塞管理

作者简介&#xff1a;一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.流量整形和监管配置 1.流量整形配置两种方式 ①流量整形的命…

从零开始上手 MQTT over QUIC:快速体验下一代物联网标准协议

前言 QUIC(RFC9000) 是下一代互联网协议 HTTP/3 的底层传输协议&#xff0c;与 TCP/TLS 协议相比&#xff0c;它在减少连接开销与消息延迟的同时&#xff0c;为现代移动互联网提供了有效灵活的传输层。 EMQX 5.0 是首个将 QUIC 引入 MQTT 的开创性产品。在长期的客户服务和技…

eunomia-bpf项目重磅开源!eBPF 轻量级开发框架来了

近日&#xff0c;在 2022 云栖大会龙蜥峰会 eBPF & Linux 稳定性专场上&#xff0c;来自 eBPF 技术探索 SIG Maintainer 、浙江大学的郑昱笙分享了《eunomia-bpf&#xff1a;eBPF 轻量级开发框架》技术演讲&#xff0c;以下为本次演讲内容&#xff1a; 大家好&#xff01;…

【新知实验室-TRTC开发】实时音视频之web端云监工系统(Vue3+Element plus+TS+Pinia)

在线上线下一体化、虚拟现实加速融合的趋势下&#xff0c;音视频已经演进成一种基本能力&#xff0c;深刻变革了社会的交互方式。未来&#xff0c;音视频作为全真互联时代的重要基石&#xff0c;将持续推动互联网和实体产业的数字化创新与升级。 今天我们将体验腾讯的实时音视…

vue3 antd table表格的增删改查(一)input输入框根据关键字搜索【后台管理系统纯前端filter过滤】

input输入框——关键字模糊搜索引言铺垫场景复现解决方案筛选的实现重置筛选信息优化处理&#xff08;监听的实现&#xff09;功能实现可能要用到的知识&#xff1a;vue3数据变化侦测&&信息筛选过滤.filter() .map() .forEach(). find()&#x1f525;vue3【watch检测/监…

[附源码]Python计算机毕业设计Django4S店汽车售后服务管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

【服务器数据恢复】IBM服务器RAID控制器出错的数据恢复案例

服务器数据恢复环境&#xff1a; 北京某公司IBM X系列某型号服务器&#xff1b; 服务器上共8块硬盘组建raid5磁盘阵列&#xff1b; 服务器上部署有oracle数据库。 服务器故障&分析&#xff1a; 服务器在运行过程中&#xff0c;raid5磁盘阵列中有2块硬盘报警&#xff0c;服务…

CRM(Mapper层)详细代码

Mapper详细代码&#xff1a; DicValueMapper&#xff1a; package com.bjpowernode.crm.settings.mapper;import com.bjpowernode.crm.settings.domain.DicValue;import java.util.List;public interface DicValueMapper {/*** This method was generated by MyBatis Generato…

制作覆盖手绘图的导游地图,非常简单,你也可以

目录 1 前言 2 手绘地图的准备 3 下载软件 4 切图软件基本设置 5 配准设置 6 从平台取得上传切片所需要的3个参数 7 程序切片 8 增加位置点 1 前言 上一篇介绍了制作“简版导游地图”的步骤&#xff0c;真的是特别简单&#xff0c;如果提前准备好了文字材料&#xff0c…

PHP转Go,框架选什么?

文章目录内功心法PHP转Go&#xff0c;优选哪个框架&#xff1f;为什么&#xff1f;为什么不火&#xff1f;GoFrame特点优势&#xff1a;劣势&#xff1a;框架选型谁适合用GoFrame谁不适合用GoFrameGoFrame框架设计思想开发流程从0到1核心步骤总结视频一起学习这是一期会引起广泛…

即时通讯赛道开打信创牌,WorkPlus为何独树一帜?

近期&#xff0c;信创火了。 随着近期国家相关政策文件的推出&#xff0c;未来三年&#xff0c;党政信创、行业信创以及央国企信创的建设&#xff0c;将迎来全面加速。业内人士认为&#xff1a;“大信创”时代或已来临&#xff01; 信创是什么&#xff1f; 信创&#xff0c;…

加载用户数据至用户维度表

目录 1.创建转换 2.配置表输入 3.配置表输入2 4.创建新转换 5.配置映射输入规范 6.配置数据库查询 7.配置数据库查询2 8.配置数据库查询3 9.配置过滤记录 10配置JavaScript代码 11.配置字段选择 12.配置映射输出规范 13.配置映射&#xff08;子转换&#xff09; 1…

JS进阶第一篇:手写call apply bind

文章目录手写call apply bind深入理解 call 方法手写call手写apply手写bind手写call apply bind 深入理解 call 方法 call 理解了&#xff0c;apply和bind就都迎刃而解了&#xff0c;他们都是大同小异。在此对call和apply不做过多的定义性解释&#xff0c;先来看下调用了call…

opencv阈值图像Threshold方法

图像阈值 固定阈值&#xff0c;自适应阈值&#xff0c;Otsu 二值化等 全局阈值和局部阈值 一、图像二值化 定义&#xff1a;图像的二值化&#xff0c;就是将图像上的像素点的灰度值设置为0或255&#xff0c;也就是将整个图像呈现出明显的只有黑和白的视觉效果。 灰度值0&…

热门Java开发工具IDEA入门指南——导出项目到Eclipse

IntelliJ IDEA&#xff0c;是java编程语言开发的集成环境。IntelliJ在业界被公认为最好的java开发工具&#xff0c;尤其在智能代码助手、代码自动提示、重构、JavaEE支持、各类版本工具(git、svn等)、JUnit、CVS整合、代码分析、 创新的GUI设计等方面的功能是非常强大的。 上文…

打工人,这里有一份述职技巧,请查收

大家好&#xff0c;马上到年底了&#xff0c;有多少小伙伴正在期待着述职邮件&#xff0c;毕竟收到述职邮件&#xff0c;也就意味着有机会升职加薪。有没有跟糖糖一样&#xff0c;没收到邮件的&#xff1f; 工作要善于总结&#xff0c;也要善于表达&#xff0c;如何在限时内将…

跨平台应用开发进阶(四十)自定义插件及引用

文章目录一、前言二、插件制作三、离线插件集成应用示例四、拓展阅读一、前言 正如将可复用功能封装为自定义组件以供他人使用一样&#xff0c;在uni-app开发框架中提供了另一种形式的自定义插件&#xff0c;并可将该插件提交至uni-app插件市场。 二、插件制作 制作插件前&a…