一、其他API
1.shallowRef 与 shallowReactive
(1)shallowRef
1. 作用:创建一个响应式数据,但只对顶层属性进行响应式处理。
2.用法:
let myVar = shallowRef(initialValue);
3. 特点:只跟踪引用值的变化,不关心值内部的属性变化。
比如:当访问person.value时可以,但是访问person内部的属性person.value.name就不行。
(2)shallowReactive
1. 作用:创建一个浅层响应式对象,只会使对象的最顶层属性变成响应式的,对象内部的嵌套属性则不会变成响应式的
2. 用法:
const myObj = shallowReactive({ ... });
3. 特点:对象的顶层属性是响应式的,但嵌套对象的属性不是。
(3)总结
通过使用 [shallowRef()]和[shallowReactive()来绕开深度响应。浅层式 `API` 创建的状态只在其顶层是响应式的,对所有深层的对象不会做任何处理,避免了对每一个内部属性做响应式所带来的性能成本,这使得属性的访问变得更快,可提升性能。就是当你只关心修改整体的时候就可以用这两个属性。
2.readonly 与 shallowReadonly
(1)readonly
1. 作用:用于创建一个对象的深只读副本。
2. 用法:
const original = reactive({ ... }); const readOnlyCopy = readonly(original);
3. 特点:
* 对象的所有嵌套属性都将变为只读。
* 任何尝试修改这个对象的操作都会被阻止(在开发模式下,还会在控制台中发出警告)。不可修改。
4. 应用场景:
* 创建不可变的状态快照。
* 保护全局状态或配置不被修改。
(2)shallowReadonly
1. 作用:与 `readonly` 类似,但只作用于对象的顶层属性。
2. 用法:
const original = reactive({ ... }); const shallowReadOnlyCopy = shallowReadonly(original);
3. 特点:
* 只将对象的顶层属性设置为只读,对象内部的嵌套属性仍然是可变的。
* 适用于只需保护对象顶层属性的场景。
3.toRaw 与 markRaw
(1)toRaw
1. 作用
用于获取一个响应式对象的原始对象, `toRaw` 返回的对象不再是响应式的,不会触发视图更新。
> 官网描述:这是一个可以用于临时读取而不引起代理访问/跟踪开销,或是写入而不触发更改的特殊方法。不建议保存对原始对象的持久引用,请谨慎使用。
> 何时使用? —— 在需要将响应式对象传递给非 `Vue` 的库或外部系统时,使用 `toRaw` 可以确保它们收到的是普通对象
2.用法
import { reactive,toRaw,markRaw,isReactive } from "vue"; /* toRaw */ // 响应式对象 let person = reactive({name:'tony',age:18}) // 原始对象 let rawPerson = toRaw(person)
比如获取person2之后,再点击修改person2的数据,就不奏效。
(2)markRaw
1. 作用
标记一个对象,使其**永远不会**变成响应式的。
例如使用`mockjs`时,为了防止误把`mockjs`变为响应式对象,可以使用 `markRaw` 去标记`mockjs`。(mockjs是一个模仿后端接口的库,只要npm i mockjs,然后import mockjs from 'mockjs'就可以使用了。)
2.使用
/* markRaw */ let citys = markRaw([ {id:'asdda01',name:'北京'}, {id:'asdda02',name:'上海'}, {id:'asdda03',name:'天津'}, {id:'asdda04',name:'重庆'} ]) // 根据原始对象citys去创建响应式对象citys2 —— 创建失败,因为citys被markRaw标记了 let citys2 = reactive(citys)
4.customRef
作用:创建一个自定义的`ref`,并对其依赖项跟踪和更新触发进行逻辑控制。
实现防抖效果
这里有一个例子,比如我要实现这样一个功能,输入一个数据,不让他立即变化,而是过了一秒钟之后再变。那么利用ref是不行的,因为他是即时的响应只要一输入就立马变化。所以我们用到了customRef.
如下图所示:
这里面要重点理解track,和trigger.
但是实际开发中,我们不这样,而是用到了hooks,可以自己写一个useMsgRef.ts
useMsgRef.vue
import { customRef } from 'vue';
export default function (initValue: string, delay: number) {
// 使用Vue提供的customRef定义响应式数据
let timer: number;
// track(跟踪)、trigger(触发)
let msg = customRef((track, trigger) => {
return {
// get何时调用?—— msg被读取时
get() {
track(); //告诉Vue数据msg很重要,你要对msg进行持续关注,一旦msg变化就去更新
return initValue;
},
// set何时调用?—— msg被修改时
set(value) {
clearTimeout(timer);
timer = setTimeout(() => {
initValue = value;
trigger(); //通知Vue一下数据msg变化了
}, delay);
},
};
});
return { msg };
}
App.vue
<template>
<div class="app">
<h2>{{ msg }}</h2>
<input type="text" v-model="msg">
</div>
</template>
<script setup lang="ts" name="App">
import { ref } from 'vue'
import useMsgRef from './useMsgRef'
// 使用Vue提供的默认ref定义响应式数据,数据一变,页面就更新
// let msg = ref('你好')
// 使用useMsgRef来定义一个响应式数据且有延迟效果
let { msg } = useMsgRef('你好', 2000)
</script>
<style scoped>
.app {
background-color: #ddd;
border-radius: 10px;
box-shadow: 0 0 10px;
padding: 10px;
}
button {
margin: 0 5px;
}
</style>
二、Vue3新组件
1.Teleport
(1)解释
什么是Teleport?—— Teleport 是一种能够将我们的**组件html结构**移动到指定位置的技术。
(2)使用
<teleport to='body' > <div class="modal" v-show="isShow"> <h2>我是一个弹窗</h2> <p>我是弹窗中的一些内容</p> <button @click="isShow = false">关闭弹窗</button> </div> </teleport>
比如我们实现一个这样的效果,点击弹窗,窗口显示在整个页面的中间。filter是实现滤镜效果。右边是实现居中效果。我们发现一旦加了filter,右边居中显示效果不奏效了,不显示在整个页面中间,而是显示在父容器中间。那么这时候就用到了teleport.
如下是使用teleport
2.Suspense
(1)等待异步组件时渲染一些额外内容,让应用有更好的用户体验
(2)使用步骤
- 异步引入组件
- 使用`Suspense`包裹组件,并配置好`default` 与 `fallback`
(3)使用场景
在子组件setup中使用axios请求一些东西,又显请求返回结果慢,想让空白的页面显示一些东西就可以用suspense.
import { defineAsyncComponent,Suspense } from "vue"; const Child = defineAsyncComponent(()=>import('./Child.vue')) ``` ```vue <template> <div class="app"> <h3>我是App组件</h3> <Suspense> <template v-slot:default> <Child/> </template> <template v-slot:fallback> <h3>加载中.......</h3> </template> </Suspense> </div> </template>
3.全局API转移到应用对象
也就是之前的全局APIApp.xxx全部变成了app.xxx
app.component
app.config
app.directive
app.mount
app.unmount
app.use
4.非兼容性改变(Vue23区别)
- 过渡类名 `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`。
......
完结!!!接下来会做关于Vue3的 项目,有需要的可以关注!