@vue/cli 创建Vue2/3的工程化项目 Vue2全家桶
- Vue@2
- Vuex@3
- Vue@router@3
- Vant@2 移动端UI组件库
- element-ui PC端UI组件库
Vue3全家桶
-
vue@3
-
Vuex@4
-
Vue-router@4
-
vant@3
-
element-plus
Vue2和Vue3的区别
Vue3的新特性
1.performance
性能上做了提高[内部重写了虚拟DOM的实现,在虚拟DOM处理的时候,跳过静态节点,只处理动态节点]
结果就是客户端渲染视图的速度提高了1.3倍到2倍之间,而服务端SSR渲染的速度提高了2~3倍
Vue视图渲染的机制 基于template/jsx语法构建视图 --> 会把视图编译为虚拟DOM对象(vnode:vue内部构建的对象,用来描述节点相关的属性特征)
-->如果是第一次渲染,会直接虚拟DOM变为真实DOM(真实DOM:放入到浏览器页面中进行渲染)
-->如果是视图更新,会重新生成虚拟DOM,和上一次生成的虚拟DOM进行对比[DOM-diff] 同级对比 由上而下比较 计算出差异的部分,再渲染的时候,只需要把有差异的部分进行渲染即可。
Vue2:基于Vue-template-compiler 这个插件实现对template视图的编译 把其编译为vnode Vue3:基于@vue/compiler-sfc这个插件实现对视图的编译
2.Tree shaking
利用webpack新版本自带的功能实现"打包优化":把没有用到的API自动剪辑掉 只打包用到的内容!! 例如:utils库中100个方法 但是项目中我们直接或间接使用的只有20个 如果"Tree shaking机制" 我们打包的还是100个方法(这样没有必要,而且文件体积还会变大) 如果具备这个机制 只会打包20个方法 打包速度变快 打包后的体积也会更小... 对于UI组件库,一般都提供了单独的"按需导入"
3.Fragment
Vue2的template视图中 只允许出现一个根节点 会导致层级过深 Vue3的template视图中 可以出现多个根节点 原理:它自己在外层嵌套Fragment空文档标记标签
<></>不占DOM层级 还能保证只有一个根节点如果vscode报红
- 效果可以实现
- 你的vscode不支持vue3的语法
更新系统「win10/11」 安装最新版本的vscode 保证Vetur也是最新版本
4.新增内置组件 <Teleport> :传送门
正常情况下,组件内部所有内容在编译完成后,都会插入到#app中渲染!! 传送门机制,可以让组件中的某一部分内容,插入到#app以外的其他容器中渲染
5.新增内置组件 : 异步组件
/* 在子组件中*/
<template>
<ul>
<li v-for="(item, index) in list" :key="index">
{{ item }}</li>
</ul>
</template>
<script>
import { defineComponent } from 'vue';
const query = function query() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve([11, 22, 33])
}, 2000)
})
}
export default defineComponent({
/* 第一次渲染组件会执行setup */
async setup(props) {
let list = await query();
/* 等待两秒后才会返回list 此时组件不会渲染 */
return {
list,
};
}
})
</script>
/*在父组件中*/
<template>
<Suspense>
<SuspenseTest></SuspenseTest>
<template #fallback>
<el-skeleton :row="3" animated></el-skeleton>
</template>
</Suspense>
</template>
<script setup>
import SuspenseTest from './views/SuspenseTest.vue';
</script>
6.更好的支持Typescript 有一些公司,已经开始采用 vite+vue3+ts 组合做开发了
7.Custom Renderer API
一般情况下 我们在视图(组件)中编写的内容都会以HTML的形式插入到页面中! Custom Renderer API中提供了一系列的方法 可以让我们在组件中编写的内容 最后绘制为对应的图形图片(canvas)以此更好的实现可视化的开发
8.Composition API
在Vue2中 我们采用的是"options API" 在Vue3中 我们也可以继续延续"options API"的写法 但是建议大家使用"Compositions API 聚合式API" 把所有的内容基本上都写在setup函数中
export default{
setup(){
....
}
}
<script setup></script>
9.在Vue3中 推荐使用"函数式编程"
Vue3中 不再有Vue这个类所以也就不存在 new Vue({})这样的操作了 而是要导出createAPP这个函数 基于这个函数执行创建对应的应用
Vue2 面向对象的方式
new Vue({
store,
router,
h=>h(APP)
})
Vue3 函数式编程
import {createApp} from 'vue'
const app = createApp(APP);
app.use(store);
app.use(router);
app.mount(#app);
10.响应式数据实现的方案做了改变
Vue2的响应式原理:基于defineproperty对数据进行劫持
Vue3的响应式原理 两种方案
以ref为主的响应式方案 依然式基于defineProperty做数据劫持
以reactive为主的响应式方案 记忆ES6的Proxy实现数据劫持
Vue3中的响应式原理:
@1 以ref为主的get/set劫持「核心还是Object.defineProperty」
@2 以reacive为主的数据劫持,是基于ES6中的Proxy实现的
特点:
+ 直接对整个对象进行代理劫持,而且对于数组每一项也是直接劫持 -> Vue3的响应式性能要强于Vue2
+ 除了做get/set劫持外,还可以实现其它方面的劫持:getPrototypeOf/setPrototypeOf/isExtensible/preventExtensions/getOwnPropertyDescriptor/defineProperty/has/deleteProperty/ownKeys/apply/construct,Vue3中实现了get/set/deleteProperty/has/ownKeys等劫持 -> Vue3响应式实现的功能要强于Vue2
+ 也像Vue2一样,基于递归对“对象”做了深层次劫持
+ ES6新增的API,不兼容IE
Vue2中的响应式原理:
+ 首先对data进行深度的监听和劫持 Object.defineProperty「ES5」
+ 对数组每一项不进行处理,而是重写了数组的原型指向「push/pop/shift/unshift/splice/sort/reverse」
特点:
+ 对“对象”中的每一项只做了get/set的劫持,只有获取及修改属性值的时候,才会触发劫持函数
+ 依次迭代对象中的每个属性,给每个属性分别做劫持
+ 对于数组每一项只是重写了原型对象,但是没有做劫持
obj.z=[...] 视图会更新
obj.z[0]=100 视图不会更新
obj.z.splice(0,1,100) 视图会更新
+ 基于递归把每一次层级都做了劫持
+ ES5劫持方法,所以兼容IE9+
+ 如果当前对象是被冻结的,则不进行劫持处理
虽然在Vue3中依然可以延续Vue2的语法 但是每一个组件(this)不在Vue类的实例 也访问不到Vue。prototype 去掉了面向对象的相关特征 常用的一些属性方法变为this的私有属性 data/methods/computed...这里编写状态/方法/计算属性 也会挂载到实例上 视图中也可以直接使用
但是类似于我们之前 在Vue.prototype.api.xxx 无法使用了
Vue3中建议使用"聚合式API":编写的内容(例如:状态、计算属性、方法、监听器....)都聚合在setup函数中
@1 只有第一次渲染组件的时候才会触发setup函数执行 【组件更新的时候不会触发】
@2 发生在"初始化props"之后 和"beforeCreate"之前
+ this --> undefined 聚合式API的模式下 我们告别了基于this操作的的时代
+ 我们可以基于props形参 获取到处理过的属性 【而且属性兑现是经过Proxy做过数据劫持的响应式数据】
不仅可以在setup中获取到 一样延续Vue2的处理 也会把属性挂载到this上一份 在视图上也可以直接使用
+ 在setup函数中基于return返回的内容 都会默认挂载到this上【虽然setup中没有this】这样也就可以直接在视图中使用了;
+ setup 函数中也并不会聚合所有东西 例如:
+ 组件的名字
+ 属性初始化
+ 注册组件
+ 注册使用上下文信息
+ ...