目录
一:shallowRef & shallowReactive
一:shallowRef & shallowReactive
目的:提升性能,绕开深度响应。浅层式 API 创建的状态只在其顶层是响应式的,对所有深层的对象不会做任何处理,避免了对每一个内部属性做响应式所带来的性能成本,这使得属性的访问变得更快,可提升性能。
shallowRef():
作用:创建一个响应式数据,但只对顶层属性进行响应式处理。ref的浅层次处理方法
特点:只跟踪引用值的变化,不关心值内部的属性变化
shallowReactive():
作用:创建一个浅层响应式对象,只会使对象的最顶层属性变成响应式的,对象内部的嵌套属性则不会变成响应式的。reactive的浅层次处理方法
特点:对象的顶层属性是响应式的,但嵌套对象的属性不是。
//第一步:引入 import { shallowRef } from 'vue' //第二步:使用 // 对于单一的 .vulue可以进行数据更改,对象的下一级不能修改,但是可以修改整个对象 let sum = shallowRef(0) let person = shallowRef({ name:'石昊', age:18 }) function changeSum (){ sum.value += 1; //可以修改 } function changeName (){ person.value.name = '王林' //不可以修改 } function changePerson (){ person.value = {name:'王林',age:500} //可以修改 }
//第一步:引入 import { shallowReactive } from 'vue' //第二步:使用 let car = shallowReactive({ barnd:'奔驰', options:{ color:'红色', engine:'V8' } }) function changeBrand(){ car.barnd = '宝马'; //可以修改 } function changeColor(){ car.options.color = '紫色'; //不可以修改 }
二:readonly & shallowReadonly
创建对象的只读副本
readonly:
对象的所有嵌套属性都将变为只读。
任何尝试修改这个对象的操作都会被阻止(开发模式下,会在控制台中发出警告)
应用场景:
创建不可变的状态快照。
保护全局状态或配置不被修改注意⚠️:只能是对象格式,不能是字符串。
import { ref, readonly } from "vue"; let sum1 = ref(0) let sum2 = readonly(sum1)
shallowReadonly:
对象的顶层属性将变为只读。浅层次的
应用场景:
只将对象的顶层属性设置为只读,对象内部的嵌套属性仍然是可变的。
适用于只需保护对象顶层属性的场景。
import { shallowReadonly } from "vue"; let car2 = shallowReadonly( 对象 )
三:toRaw & markRaw
toRaw:
获取一个响应式对象的原始对象, toRaw 返回的对象不再是响应式的,不会触发视图更新
应用场景:在需要将响应式对象传递给非Vue的库或外部系统时, 使用toRaw可以确保它们收到的是普通对象
import { reactive,toRaw } from "vue"; let person = reactive({ name:'tony', age:18 }) // 用于获取一个响应式对象的原始对象 let rawPerson = toRaw(person);
markRaw:
标记此对象,使其永远不会变成响应式
import { reactive,markRaw } from "vue"; let city = markRaw([ {id:'01',name:'北京'}, {id:'02',name:'上海'}, {id:'03',name:'天津'}, {id:'04',name:'重庆'} ]) //永远不会在变成响应式数据 let city2 = reactive(city) //创建响应式失败
四:customRef
创建一个自定义的ref,并对其依赖项 跟踪和更新触发 进行逻辑控制
比如实现防抖效果,延迟接口请求等操作
重点理解这两个方法:
track(跟踪):告诉vue数据msg很重要,要对它进行持续跟踪,一旦有变化就去更新
trigger(触发):通知vue,数据msg变化了
//第一步:引入customRef import { customRef } from 'vue' //第二步:使用customRef // 自定义ref:customRef,数据一变,可以延迟更新 // 基本格式 let msg = customRef((track,trigger) => { return { get(){ track(); return '123'; }, set(value){ console.log('新值=', value); trigger(); } } })
一般会使用hooks进行封装,下边是封装的一个msg的hooks,实现延迟更改字符串信息
import { customRef } from 'vue' export default function(initValue:string, delayTime:number ){ let timer:any; const msg = customRef((track,trigger) => { return { //get调用时间? - msg被读取时 get(){ //读数据 先调track track(); return initValue }, //set调用时间? - msg被修改时 set(value){ // 修改数据可以进行其他的逻辑操作 console.log('set',value); clearInterval(timer); timer = setTimeout(() => { initValue = value; //改数据后在调trigger trigger(); }, delayTime); } } }) return {msg} }
五:teleport
说明:Teleport 是一种能够将我们的 组件html结构 移动到指定位置的技术
<!-- teleport包裹需要移动的html结构 to='body':插入到对应的标签上,可以是普通标签,类或id --> <teleport to='body'> <div class="modal" v-show="isShow"> <h2>我是弹窗的标题</h2> <p>我是弹窗的内容</p> <button @click="isShow = false">关闭弹窗</button> </div> </teleport>
有这么一个问题:弹窗在元素使用 filter: saturate(200%) - [滤镜]之后 position: fixed; 据对定位会失效(不再针对浏览器的可视区域进行定位,而是相对于组件容器定位)
加上teleport (左侧)和 不加(右侧) 的区别
六:Suspense
等待异步组件时渲染一些额外内容,让应用有更好的用户体验
使用步骤:
1: 异步引入组件 import {Suspense} from 'vue'
2: 使用`Suspense`包裹组件,并配置好插槽的default 与 fallback
<Suspense> <template v-slot:default> <suspenseChild/> </template> <template v-slot:fallback> <h2>加载中......</h2> </template> </Suspense>
七:全局API转移到应用对象
app.component
app.config
app.directive
app.mount
app.unmount
app.use
八:非兼容性的改变
过渡类名v-enter修改为v-enter-from、过渡类名v-leave修改为v-leave-from。
keyCode作为v-on修饰符的支持。
v-model指令在组件上的使用已经被重新设计,替换掉了v-bind.sync。
v-if和v-for在同一个元素身上使用时的优先级发生了变化。
移除了$on、$off和$once实例方法。
移除了过滤器filter。
移除了$children实例propert。