一、组合式API
1.shallowReactive与shallowRef
- shallowReactive :只处理对象最外层属性的响应式(浅响应式)。shallowRef :只处理基本数据类型的响应式,不进行对象的响应式处理。
- 什么时候使用?
- 如果有一个对象数据,结构比较深,但变化时只是外层属性变化===> shallowReactive
- 如果有一个对象数据,后续功能不会修改该对象中的属性,而是生新的对象来替换===> shallowRef
2.readonly与shallowReadonly
- readonly:让一个响应式数据变为只读的(深只读)
- shallowReadonly:让一个响应式数据变为只读的(浅只读)
- 应用场景:不希望数据被修改
3.toRaw与markRaw
普通数据--------reactive/ref------------->响应式数据
<------------toRaw---------------
-
toRaw :
- 作用:将一个由 reactive生成的响应式对象转为普通对象。
- 使用场景:用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新。
-
markRaw :
- 作用:标记一个对象,使其永远不会再成为响应式对象。
- 应用场景:
- 有些值不应被设置为响应式的,例如复杂的第三方类库等。
- 当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能。
4.customRef(自定义ref)
作用:创建一个自定义的 ref ,并对其依赖项跟踪和更新触发进行显式控制。
//自定义一个ref——名为myRef
import {custonRef} from 'vue'
setup(){
function myRef(value){
return customRef(track,trigger)={
get(){
console.log('有人从myRef这个容器中读取数据了,我把value给他了')
track()//通知vue追踪value变化(提前告诉get,value是有用的)
return value
}
set(newValue){
console.log('有人把myRef这个容器中数据了,改为了newValue')
value=newValue
trigger()//通知vue重新解析模板
}
}
}
//使用程序员自定义的ref
let key=myRef('hello')
return{
key
}
}
- 可以使用customRef实现防抖效果
<template>
<input type="text" v-model="keyword">
<h3>{{ keyword }}</h3>
</template>
<script>
import {ref,customRef} from 'vue'
export default{
name:'demo',
setup() {
function myRef(value,delay){
let timer
return customRef(track,trigger)={
get(){
console.log('有人从myRef这个容器中读取数据了,我把value给他了')
track()//通知vue追踪value变化(提前告诉get,value是有用的)
return value
}
set(newValue){
console.log('有人把myRef这个容器中数据了,改为了newValue')
clearTimeout(timer)
timer=setTimeout(()=>{
value=newValue
trigger()//通知vue重新解析模板
},delay)
}
}
}
//使用程序员自定义的ref
let key=myRef('hello',500)
return{
key
}
}
}
</script>
5.provide与inject
- 作用:实现祖孙间通信
- 套路:父组件有一个provide选项来提供数据,后代组件有一个inject选项来开始使用这些数据
祖组件中
setup(){
......
let car=reactive({name:'奔驰',price:'40w'})
provide('car',car)
}
孙组件中
setup(props,context){
const car=inject('car')
return {car}
......
}
6.响应式数据的判断
- isRef ():检查一个值是否为一个 ref 对象
- isReactive() :检查一个对象是否是由 reactive 创建的响应式代理
- isReadonly() :检查一个对象是否是由 readonly 创建的只读代理
- isProxy ():检查一个对象是否是由| reactive 或者 readonly 方法创建的代理
二、新的组件
1.Fragment
- 在Vue2中:组件必须有一个根标签
- 在Vue3中:组件可以没有根标签,内部会将多个标签包含在一个 Fragment 虚拟元素中
- 好处:减少标签层级,减小内存占用
2.Teleport
Teleport 是一种能够将我们的组件 html 结构移动到指定位置的技术。
< teleport to ="移动位置(body/html)">
< div v - if =" isShow " class =" mask ">
< div class =" dialog ">
<h3>我是一个弹窗</h3>
< button @ click =" isShow = false ">关闭弹窗</ button >
</ div >
</ div >
</ teleport >
3.suspense(以后可能会改)
//静态引入
import child from './component/child'
//异步引入
import {defineAsyncComponent} from 'vue'
const child=defineAsyncComponent(()=>import('./component/child'))
使用suspense包裹组件,并配置好default与fallback
< template >
< div class =" app ">
<h3>我是 App 组件</h3>
< Suspense >
< template v - slot : default >
< Child />
</ template >
< template v - slot : fallback >//default未出现时才展示
<h3>加载中..…</h3>
</ template >
</ Suspense >
</ div >
</ template >
三、其他变化
1.全局API的转移
2.其他改变
(1)data选项始终被声明为一个函数
(2)过度类名更改
v-enter ===> v-enter-from
v-leave ===> v-leave-from
(3)移除了keyCode作为v-on的修饰符,也不支持config.keyCodes
(4)移除了v-on.native修饰符
父组件中绑定事件
<child
v-on:close='handleComponentEvent'
v-on:click='handleNativeClickvent'
/>
子组件中声明自定义事件
<script>
export default{
emits:['close']
}
</script>
(5)移除过滤器