这是我参与更文挑战的第24天,活动详情查看: 更文挑战
1,环境搭建
1, CDN引入最新的vue3
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.11/vue.global.prod.js"></script>
2, 升级vue-cli 升级到v4.5版本以上
npm i -g @vue/cli@next
-注意事项:最好提前卸载掉之前的版本,不然使用的时候,很有可能还是vue2, 最好的办法就是卸载完之后重启一下, 升级完之后,查看版本:
vue -V > 4.5版本以上即可
vue create vue-cli-test
npm run serve
按向下的箭头
2,项目创建
通过vite创建
# 安装create-vite-app
npm install -g create-vite-app
# 通过vite-app创建vite-app-test的项目
npm init vite-app projectName 或者 create-vite-app projectName
npm install
npm run dev
3,Vue3新特性总结
**(1)V3.0 六大亮点 **
- Performance: 性能比Vue2.0快1~2倍
- Three shaking support: 按需编译,体积比Vue2更快
- Composition API: 组合API,(类型React Hooks)
- Better TypeScript support: 更好的支持TS
- Custom Renderer API: 暴露了自定义渲染API
- Fragment, Teleport, Suspense: 更先进的组件
**(2)V3.0 是如何实现变快的 **
(1)Vue2中的虚拟dom进行全量的对比
(2)Vue3新增 了静态标记PatchFlag,在与上次虚拟dom节点进行对比的时候,只对比带有pathFlag的节点,并且可以
通过flag的信息得知当前节点要对比的具体的内容
- hoistStatic 静态提升
(1) Vue2中无论元素是否参与更新,每次都会重新创建
(2) Vue3中对于不参与更新的元素,只会创建一次,之后会在每次渲染的时候被不停的复用
- cacheHandlers 事件侦听器缓存
(1) 默认情况下onClick会被视为动态绑定,所以每次都会去追踪它的变化,但是因为是同一个函数,所以没有追踪变
化,直接缓存起来复用即可
- SSR渲
(1) 当有大量静态的内容时候,这些内容会被当作纯字符串推荐一个buffer里面,即使粗在动态绑定,
会通过模板插值嵌入进去,这样回避通过虚拟dom来渲染的快上很多很多
(2) 当静态内容大到一定量及时候,会用createStaticVNode方法在客户端
4,Composition API
-
setup() 函数是组合API的入口函数
-
简单数据变量的声明:ref
-
复杂数据变量的声明:reactive
(1) setup()执行时机
beforeCreate: 表示组件刚刚被创建出来,组件的data,methods还没有初始化好
setup()
Created: 表示组件刚刚被创建出来,并且组件的data,method已经初始化好
注意点:
1,由于在执行setup()函数的时候,还没有执行created生命周期的方法,所以在setup函数中,
是无法使用data,和methods
2,由于我们无法在setup中使用data,methods,所以Vue为了避免我们错误的使用,直接把setup中的
this修改成了undefined
3,setup只能是同步的,不能是异步的
(2) 什么是reactive?
-
reactive是Vue3.0中提供的实现响应数据的方法
-
Vue2.0中响应数据是通过defineProperty实现的
-
Vue3.0中响应数据是通过ES6中Proxy来实现的:一个响应式数据, Vue3的本质是将传入的数据包装成一个 Proxy对象
**reactive注意点: **
1, 参数必须是一个对象(json/arr),如果想监听一个变量,vue3提供了ref.
2, 如果给reactive传递了其他对象,默认情况下修改对象,界面不会自动更新
如果想更新,可以通过重新赋值的方式
(3) 什么是ref?
-
ref和reactive一样,也是用来实现响应式数据的方法
-
由于reactive必须传递一个对象,导致开发中想让某个变量实现响应式就非常麻烦,所以vue3提供了ref,实现简单值得监听
-
ref的本质: ref的本质其实还是reactive
-
ref的原理其实也是自动把ref转换成reactive对象
ref(18) => reative({value:18)
**注意点:**如果是通过ref创建的数据,在template中使用不用通过.value来获取,因为Vue会自动给我们添加.value
(4) ref 和 reactive的区别?
1, 如果在template里面使用的是ref类型的数据,那么Vue会自动帮我们添加.value
2, 如果在template里面使用的是reactive类型的数据,那么Vue不会自动帮我们添加.value
3, Vue在解析数据之前,会自动判断这个数据是否是ref类型,若是自动添加.value,
如果不是就不自动添 加.value
4, 怎么判断是ref类型,还是reactive类型,Vue3提供了一个私有属性__v_isRef : true
或者 我们自己也可以判断:isRef(), isReactive()
(5)递归监听&&非递归监听
1, 默认情况:无论是ref还是reactive,都是递归监听,如果数据量很大,非常消耗性能
2, 只监听第一层,如果第一层变化了,页面就更新
如果是ref类型: shallowRef, 如果是reactive类型: shallowReactive
本质:shallowReactive 只监听第一层数据变化,
如果第一层数据变化了,整个UI都更新,
如果第一层数据没有变化,UI不变
如果是通过shallowRef 创建的数据,那么Vue监听的是.value变化,并不是第一层的变化
如果只是想监听第几个变化,根据传递的做修改 triggerRef
3, 应用场景:
一般情况下我们使用ref, reactive即可,只有在需要监听数据量比较大的时候,我们才使用shallowRef, shallowReactive
4, shallowRef, shallowReactive的本质:
shallowRef(10) 底层还是-> shallowReactive({value:10}) 他监听的是.value的变化
(6)toRaw: 获取原始数据
如果直接修改obj,那么无法触发页面更新,只有通过包装之后的对象来修改,才会触发界面更新
1, 如果是reactive包装的对象,获取原始对象:toRaw
2, 如果想通过toRaw拿到ref类型的数据,需要通过toRaw.value获取
3, 作用:ref/reactive数据类型的特点: 每次修改都会被追踪,都会更新UI界面,但是这样其实非常消耗性能的。
所以如果我们有一些操作不需要追踪,不需要更新UI界面,那么这个时候,我们就可以通过toRaw获取到他的原始数
据,对数据进行修改
(7)markRow 数据永远不被追踪
let obj = {name:'zlm', age: 19}
obj = markRow(obj)
let state = reactive(obj)
(8)ref和toRef的区别
1, ref 复制,修改响应式数据不会影响以前的数据
2, toRef 应用,修改响应式数据会影响以前的数据
3, ref: 数据发生变化,界面就回自动更新
4, toRef 数据发生变化,界面也不会自动更新
5, toRef应用场景: 如果想让响应式数据和以前的数据关联起来,并且更新响应式数据之后还不想更新UI,
那么就可以使用toRef
toRef(obj, 'name')
(9) toRefs
如果是对象里面的多个属性都想实现响应式,可以用toRefs
-
customRef 自定义
function myRef(value) { return customRef((track, trigger) => { return { get() { track() // 告诉Vue这个数据是需要追踪变化的 return value }, set(newValue) { value = newValue trigger() // 告诉Vue触发界面更新 } } }) }
5,技巧总结
1,获取元素DOM
ref.value
2,readyonly, isReadonly, shallowReadonly
readonly: 用于创建一个只读数据,并且是递归只读
shallowReadonly: 用于创建一个只读数据,但是不是递归只读,只有第一层只读
isReadonly: 判断是否是只读数据
3,Compositon API 和 Option API 可混合使用
Compositon的本质: 声明了一个age, 它的本质是注入到data中
4,Vue3响应式数据本质
vue2中是通过defineProperty来实现响应式数据
Vue3中是通过Proxy来实现响应式数据的