文章目录
- 一、Vue3 新特性
- 1.1 重写双向数据绑定
- 1.1.1 Vue2 基于Object.defineProperty() 实现
- 1.1.2 Vue3 基于Proxy 实现
- 1.2 优化 虚拟DOM
- 1.3 Fragments
- 1.4 Tree shaking
- 1.5 Composition API
- 二、 vue-devtools 调试工具
- 三、环境配置
- 四、脚手架目录介绍
- 五、SFC 语法规范解析
- 附录:推荐采用国内淘宝镜像策略
一、Vue3 新特性
1.1 重写双向数据绑定
1.1.1 Vue2 基于Object.defineProperty() 实现
数字化管理平台
Vue3+Vite+VueRouter+Pinia+Axios+ElementPlus
权限系统-商城
个人博客地址
把 Vue 中的核心方法 defineReactive 做一些简化如下:
function defineReactive (obj, key, val, cb) {
var dep = new Dep();
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: ()=>{
/*....依赖收集等....*/
dep.depend()
return val
},
set:newVal=> {
val = newVal;
/*触发回调*/
dep.notify()
}
})
}
Vue通过defineReactive方法实现对需要观察的对象的每个属性进行监控。dep对象就相当于一个调度中心的作用,如果有数据用到这个属性,它就会自动收集该属性到调度中心,如果某属性发生了改变,那就会通知调度中心来更新视图。
1.1.2 Vue3 基于Proxy 实现
let proxyObj = new Proxy(obj,{
get : function (target,prop) {
return prop in target ? target[prop] : 0
},
set : function (target,prop,value) {
target[prop] = 888;
}
})
Proxy 与 Object.defineProperty(obj, prop, desc)方式相比有以下优势:
- 丢掉麻烦的备份数据**
- 省去for in 循环
- 可以监听数组变化
- 代码更简化
- 可以监听动态新增的属性
- 可以监听删除的属性
- 可以监听数组的索引和 length 属性
1.2 优化 虚拟DOM
在Vue2中,每次更新diff,都是全量对比,Vue3则只对比带有标记的,这样大大减少了非动态内容的对比消耗
Vue Template Explorer我们可以通过这个网站看到静态标记
-
patch flag 优化静态树
<span>Hello world!</span> <span>Hello world!</span> <span>Hello world!</span> <span>Hello world!</span> <span>{{msg}}</span> <span>Hello world!</span> <span>Hello world! </span>```
-
Vue3
编译后的Vdom
是这个样子的export function render(_ctx,_cache,$props,$setup,$data,$options){return (_openBlock(),_createBlock(_Fragment,null,[ _createvNode( "span", null,"Hello world ! "), _createvNode( "span",null,"Hello world! "), _createvNode( "span",null,"Hello world! "), _createvNode( "span", null,"Hello world! "), _createVNode("span", null,_toDisplaystring(_ctx.msg),1/* TEXT */), _createvNode( "span", null,"Hello world! "), _createvNode( "span", null,"Hello world! ")],64/*STABLE_FRAGMENT */))
-
新增了 patch flag 标记
TEXT = 1 // 动态文本节点 CLASS=1<<1,1 // 2//动态class STYLE=1<<2,// 4 //动态style PROPS=1<<3,// 8 //动态属性,但不包含类名和样式 FULLPR0PS=1<<4,// 16 //具有动态key属性,当key改变时,需要进行完整的diff比较。 HYDRATE_ EVENTS = 1 << 5,// 32 //带有监听事件的节点 STABLE FRAGMENT = 1 << 6, // 64 //一个不会改变子节点顺序的fragment KEYED_ FRAGMENT = 1 << 7, // 128 //带有key属性的fragment 或部分子字节有key UNKEYED FRAGMENT = 1<< 8, // 256 //子节点没有key 的fragment NEED PATCH = 1 << 9, // 512 //一个节点只会进行非props比较 DYNAMIC_SLOTS = 1 << 10 // 1024 // 动态slot HOISTED = -1 // 静态节点 BALL = -2
我们发现创建动态 dom 元素的时候,Vdom 除了模拟出来了它的基本信息之外,还给它加了一个标记: 1 /* TEXT */,这个标记就叫做 patch flag(补丁标记)。patch flag 的强大之处在于,当你的 diff 算法走到 _createBlock 函数的时候,会忽略所有的静态节点,只对有标记的动态节点进行对比,而且在多层的嵌套下依然有效。尽管 JavaScript 做 Vdom 的对比已经非常的快,但是 patch flag 的出现还是让 Vue3 的 Vdom 的性能得到了很大的提升,尤其是在针对大组件的时候。
1.3 Fragments
-
vue3 允许我们支持多个根节点
<div>Hello World</div> <div>Hello Vue</div> <div :key="index" v-for="item,index in [10,20,304]">{{item}}</div>
-
同时支持render JSX 写法
render() { return ( <> {this.visable ? ( <div>{this.obj.name}</div> ) : ( <div>{this.obj.price}</div> )} <input v-model={this.val}></input> {[1, 2, 3].map((v) => { return <div>{v}-----</div>; })} </> ); },
-
同时新增了Suspense teleport 和 多 v-model 用法
1.4 Tree shaking
简单来讲,就是在保持代码运行结果不变的前提下,去除无用的代码。
在Vue2中,无论我们使用什么功能,它们最终都会出现在生产代码中。主要原因是Vue实例在项目中是单例的,捆绑程序无法检测到该对象的哪些属性在代码中被使用到。而 Vue3源码引入tree shaking特性,将全局 API 进行分块。如果你不使用其某些功能,它们将不会包含在你的基础包中。就是比如你要用watch 就是import {watch} from ‘vue’ 其他的computed 没用到就不会给你打包减少体积
1.5 Composition API
组合式 API (Composition API) 是一系列 API 的集合,使我们可以使用函数而不是声明选项的方式书写 Vue 组件。它是一个概括性的术语,涵盖了以下方面的 API:
响应式 API:例如 ref() 和 reactive(),使我们可以直接创建响应式状态、计算属性和侦听器。
生命周期钩子:例如 onMounted() 和 onUnmounted(),使我们可以在组件各个生命周期阶段添加逻辑。
依赖注入:例如 provide() 和 inject(),使我们可以在使用响应式 API 时,利用 Vue 的依赖注入系统。
组合式 API 是 Vue 3 及 Vue 2.7 的内置功能。对于更老的 Vue 2 版本,可以使用官方维护的插件 @vue/composition-api。在 Vue 3 中,组合式 API 基本上都会配合
<script setup>
import { ref, onMounted } from 'vue'
// 响应式状态
const count = ref(0)
// 更改状态、触发更新的函数
function increment() {
count.value++
}
// 生命周期钩子
onMounted(() => {
console.log(`计数器初始值为 ${count.value}。`)
})
</script>
<template>
<button @click="increment">点击了:{{ count }} 次</button>
</template>
使用组合式 API 有以下几点优势:
- 更好的逻辑复用
组合式 API 最基本的优势是它使我们能够通过组合函数来实现更加简洁高效的逻辑复用。在选项式 API 中我们主要的逻辑复用机制是 mixins,而组合式 API 解决了 mixins 的所有缺陷。
组合式 API 提供的逻辑复用能力孵化了一些非常棒的社区项目,比如 VueUse,一个不断成长的工具型组合式函数集合。 - 更灵活的代码组织
同一个逻辑关注点相关的代码被归为了一组:我们无需再为了一个逻辑关注点在不同的选项块间来回滚动切换。此外,我们现在可以很轻松地将这一组代码移动到一个外部文件中,不再需要为了抽象而重新组织代码,大大降低了重构成本,这在长期维护的大型项目中非常关键。 - 更好的类型推导
组合式 API 主要利用基本的变量和函数,它们本身就是类型友好的。用组合式 API 重写的代码可以享受到完整的类型推导,不需要书写太多类型标注。大多数时候,用 TypeScript 书写的组合式 API 代码和用 JavaScript 写都差不太多! - 更小的生产包体积
搭配<script setup>
使用组合式 API 比等价情况下的选项式 API 更高效,对代码压缩也更友好。这是由于<script setup>
形式书写的组件模板被编译为了一个内联函数,和<script setup>
中的代码位于同一作用域。不像选项式 API 需要依赖 this 上下文对象访问属性,被编译的模板可以直接访问<script setup>
中定义的变量,无需从实例中代理。这对代码压缩更友好,因为本地变量的名字可以被压缩,但对象的属性名则不能。
二、 vue-devtools 调试工具
vue 官方提供的vue-devtools调试工具,能够方便开发者对vue 项目进行调试与开发。Chrome 浏览器在线安装vue-devtools
-
vue 2.x 调试工具
https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd
-
vue 3.x 调试工具
https://chrome.google.com/webstore/detail/vuejs-devtools/ljjemllljcmogpfapbkkighbhhppjdbg
注意:vue2 和vue3 的浏览器调试工具不能交叉使用!
点击Chrome 浏览器右上角的 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-clRSTwtM-1672016260783)(Vue3课程笔记导读.assets/image-20221225220407446.png)] 按钮,选择更多工具-> 扩展程序-> Vue.js devtools 详细信息,并勾选如下的两个选项:
注意:修改完配置项,须重启浏览器才能生效!
在浏览器中访问一个使用了vue 的页面,打开浏览器的开发者工具,切换到Vue 面板,即可使用vue-devtools调试当前的页面。
三、环境配置
-
开发环境:Vite3+ Vue3
- 兼容性:Vite 需要 Node.js版本 14.18+,16+。然而,有些模板需要依赖更高的 Node 版本才能正常运行,当你的包管理器发出警告时,请注意升级你的 Node 版本。
- Vue3 采用组合式 API
-
官方推荐的 IDE 配置: Visual Studio Code
-
Vite 搭建脚手架:
执行如下命令初始化项目
npm init vue@latest
这一指令将会安装并执行 create-vue,它是 Vue 官方的项目脚手架工具。你将会看到一些诸如 TypeScript 和测试支持之类的可选功能提示:
✔ Project name: … <your-project-name> ✔ Add TypeScript? … No / Yes ✔ Add JSX Support? … No / Yes ✔ Add Vue Router for Single Page Application development? … No / Yes ✔ Add Pinia for state management? … No / Yes ✔ Add Vitest for Unit testing? … No / Yes ✔ Add Cypress for both Unit and End-to-End testing? … No / Yes ✔ Add ESLint for code quality? … No / Yes ✔ Add Prettier for code formatting? … No / Yes Scaffolding project in ./<your-project-name>... Done.
如果不确定是否要开启某个功能,你可以直接按下回车键选择
No
。在项目被创建后,通过以下步骤安装依赖并启动开发服务器:cd <your-project-name> npm install npm run dev
注:也可以采用 vite 官方命令配置 vue 项目:
npm init vite@latest # or npm create vite@latest
安装 sass 预处理语言:
npm install --save-dev sass
四、脚手架目录介绍
- public 下面的不会被编译 可以存放静态资源
- assets 下面可以存放可编译的静态资源
- components 下面用来存放我们的组件
- router 存放路由相关文件
- stores 存放状态管理相关文件
- App.vue 是全局组件
- main.js 全局的 js 文件
- index.html 非常重要的入口文件 (Vite 的入口文件是一个 html 文件,他刚开始不会编译这些 js 文件 只有当你用到的时候 如script src=“xxxxx.js” 会发起一个请求被vite拦截这时候才会解析js文件)
- vite.config.js 这是vite的配置文件具体配置项 后面会详解
五、SFC 语法规范解析
*.vue
件都由三种类型的顶层语法块所组成:<template>
、<script>
、<style>
<template>
- 每个
*.vue
文件最多可同时包含一个顶层<template>
块。 - 其中的内容会被提取出来并传递给
@vue/compiler-dom
,预编译为JavaScript
的渲染函数,并附属到导出的组件上作为其render
选项。
- 每个
<script>
- 每一个
*.vue
文件可以有多个<script>
块 (不包括<script setup>
) - 该脚本将作为
ES Module
来执行。 - 其默认导出的内容应该是 Vue 组件选项对象,它要么是一个普通的对象,要么是 defineComponent 的返回值。
- 每一个
<script setup>
- 每个 *.vue 文件最多只能有一个
<script setup>
块 (不包括常规的<script>
) - 该脚本会被预处理并作为组件的
setup()
函数使用,也就是说它会在每个组件实例中执行。<script setup>
的顶层绑定会自动暴露给模板。更多详情请查看<script setup>
文档。
- 每个 *.vue 文件最多只能有一个
<style>
- 一个
*.vue
文件可以包含多个<style>
标签。 <style>
标签可以通过scoped
或module attribute
(更多详情请查看 SFC 样式特性) 将样式封装在当前组件内。多个不同封装模式的<style>
标签可以在同一个组件中混用。
- 一个
附录:推荐采用国内淘宝镜像策略
全局安装淘宝镜像
npm install -g cnpm --registry=https://registry.npm.taobao.org