Vue 3.0介绍
Vue 2.x 与 Vue 3.0区别
- 源码组织方式的变化
- Vue 3.0的源码全部采用TypeScript重写
- 使用Monorepo方式来组织项目结构,把独立的功能模块都提取到不同的包中
- Composition API
Vue 3.0代码虽然重写,但是90%以上的API兼容2.x,并且增加了Composition API(组合API),是用来解决Vue 2.x在开发大型项目时遇到超大组件,使用options API不好拆分和重用的问题。 - 性能提升
Vue 3.0使用Proxy重写了响应式代码,并对编译器做了优化,重写了虚拟DOM,从而让渲染和update的性能都有了大幅度的提升,另外服务端渲染的性能也提升了2-3倍。 - Vite
官方提供了一个开发工具Vite,使用Vite在开发和测试阶段,不用打包项目,可以直接去运行项目,提升了开发的效率。
Vue 3.0不同构建版本
packages/vue
构建版本
- cjs
- vue.cjs.js
- vue.cjs.prod.js
- global
- vue.global.js
- vue.global.prod.js
- vue.runtime.global.js
- vue.runtime.global.prod.js
- browser
- vue.esm-browser.js
- vue.esm-browser.prod.js
- vue.runtime.esm-browser.js
- vue.runtime.esm-browser.prod.js
- bundler
- vue.esm-bundler.js
- vue.runtime.esm-bundler.js
Composition API设计动机
- RFC (Request For Comments)
https://github.com/vuejs/rfcs - Composition API RFC
https://composition-api.vuejs.org
设计动机
- Options API(Vue 2.x)
- 包含一个描述组件选项(data、methods、props等)的对象
- Options API开发复杂组件,同一个功能逻辑的代码被拆分到不同选项
- Options API难以提取组件中可重用的逻辑,虽然有mixin,但容易命名冲突,数据来源不清晰。
- Composition API(Vue 3.0)
- Vue 3.0新增的一组API
- 一组基于函数的API
- 可以更灵活的组织组件的逻辑
性能提升
- 响应式系统升级
- Vue 2.x中响应式系统的核心是defineProperty
- Vue 3.0中使用Proxy对象重写响应式系统
- 可以监听动态新增的属性
- 可以监听删除的属性
- 可以监听数组的索引和length属性
- 编译优化
- Vue 2.x中通过标记静态根节点,优化diff的过程
- Vue 3.0中标记和提升所有的静态根节点,diff的时候只需要对比动态节点内容
- Fragments(升级vetur插件)
- 静态提升
- Patch flag
- 缓存事件处理函数
- 源码体积的优化
- Vue 3.0中移除了一些不常用的API(如inline-template、filter等)
- Tree-shaking
Vite
ES Module
- 现代浏览器都支持ES Module(IE不支持)
- 通过下面的方式加载模块
- 支持模块的script默认延迟加载(相当于省略了defer属性)
- 类似于script标签设置defer
- 在文档解析完成后,触发DOMContentLoaded事件前执行(加载模块并执行,是在DOM创建之后,并且在DOMContentLoaded执行之前执行的)
Vite与Vue-cli区别
- Vite在开发模式下不需要打包可以直接运行
- Vue-cli开发模式下必须对项目打包才可以运行
- Vite在生产环境下使用Rollup打包
基于ES Module的方式打包 - Vue-cli使用webpack打包
Vite特点
- 快速冷启动
- 按需编译
- 模块热更新
Vite创建项目
- Vite创建项目
- 基于模板创建项目
Composition API
生命周期钩子函数![在这里插入图片描述](https://img-blog.csdnimg.cn/202104181727592.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zOTk2MzQzNg==,size_16,color_FFFFFF,t_70)
reactive/toRefs/ref
- reactive:把传入的对象包装成了Proxy对象。把一个对象转换成响应式数据。
- toRefs:把对象的每一个属性都转换成响应式数据,故可以解构toRefs返回的对象,解构的每一个属性也都是响应式的。
- ref:把普通数据转换成响应式数据,它可以把基本类型的数据包装成响应式对象。
Computed
作用:
简化模板中的代码,可以缓存计算结果,当数据变化后才会重新计算。
用法:
- 第一种用法
watch(() => count.value+1) - 第二种用法
Watch
作用
侦听器,监听响应式数据的变化,执行相应的回调函数,可以获取到监听数据的新值和旧值。
Watch的三个参数
- 第一个参数:要监听的数据
- 第二个参数:监听到数据变化后执行的函数,这个函数有两个参数分别是新值和旧值
- 第三个资产:选项对象,deep和immediate
Watch的返回值
取消监听的函数。
WatchEffect
- 是Watch函数的简化版本,也用来监视数据的变化
- 接收一个函数作为参数,监听函数内响应式数据的变化
ToDoList示例
ToDoList功能列表
- 添加待办事项
- 删除待办事项
- 编辑待办事项
- 切换待办事项
- 存储待办事项
vue环境准备
- 升级vue脚手架版本为4.5以上:npm i -g @vue/cli
- 创建vue 3.0的项目:vue create projectName
代码实现
App.vue
<template>
<section id="app" class="todoapp">
<header class="header">
<h1>todos</h1>
<input
class="new-todo"
placeholder="What needs to be done?"
autocomplete="off"
autofocus
v-model="input"
@keyup.enter="addTodo"
/>
</header>
<section class="main" v-show="count">
<input id="toggle-all" class="toggle-all" type="checkbox" v-model="allDone" />
<label for="toggle-all">Mark all as complete</label>
<ul class="todo-list">
<li
v-for="todo in filteredTodos"
:key="todo"
:class="{editing: todo === editingTodo, completed: todo.completed}"
>
<div class="view">
<input class="toggle" type="checkbox" v-model="todo.completed" />
<label @dblclick="editTodo(todo)">{
{
todo.text}}</label>
<button class="destroy" @click="remove(todo)"></button>
</div>
<input
class="edit"
type="text"
v-model="todo.text"
v-editing-focus="todo===editingTodo"
@keyup.enter="doneEdit(todo)"
@blur="doneEdit(todo)"
@keyup.esc="cancelTodo(todo)"
/>
</li>
</ul>
</section>
<footer class="footer" v-show="count">
<span class="todo-count">
<strong>{
{
remainingCount}}</strong>
{
{
remainingCount>1? 'items':'item'}} left
</span>
<ul class="filters">
<li>
<a href="#/all">All</a>
</li>
<li>
<a href="#/active">Active</a>
</li>
<li>
<a href="#/completed">Completed</a>
</li>
</ul>
<button
class="clear-completed"
@click="removeCompleted"
v-show="count>remainingCount"
>Clear completed</button>
</footer>
</section>
<footer class="info">
<p>Double-click to edit a todo</p>
<!-- Remove the below line ↓ -->
<p