之后我们补充说明一些额外的函数及使用

shallowRef和shallowReactive

对响应式数据进行浅处理,即指处理一层,而不会关注深层次的变化

这一点主要是应对,如果我们有多层的对象数据,就可以使用shallowRef进行处理,减少内存消耗。

就比如我们有一个对象

{

barnd:’奔驰’,

options:{

color:’红色’,

engine:’V8′

}

}

如果使用的是reactive的话,那么无论修改哪一级的数据,都可以进行响应式的修改

但是如果是使用shallowReactive的话,尝试修改options中的数据的时候,由于超过了一级,所以并不会出现响应式效果

但是如果直接替换options的话,那么是可以生效的

同理,shallowRef也是一样的处理效果

其次是readonly和shallowReadonly

如果是readonly,使用方法如下

import { ref,reactive,readonly,shallowReadonly } from “vue”;

let sum = ref(0)

let sumonly = readonly(sum)

这样,当我们尝试修改sumonly的时候,就会进行报错,并无法生效

而对原始数据进行修改的时候,那么也会体现到sunonly之上。

shallowReadonly则是readonly的简化版,当我们有多级的对象的时候,shallowReadonly只保证第一级的对象无法被修改,我们进行一下举例

let car1 = reactive({

brand:’奔驰’,

options:{

color:’红色’,

price:100

}

})

let car2= shallowReadonly(car1)

function changeBrand(){

car2.brand= ‘宝马’

}

function changeColor(){

car2.options.color= ‘绿色’

}

function changePrice(){

car2.options.price += 100

}

对于brand的修改,由于是存在于第一级的,所以无法进行修改

但是针对options中的修改,那么就可以进行修改完成。

适合只需要保护对象顶层的场景。

toRaw和markRaw

分别用于保护响应式对象不被修改的,相当于声明了readonly

但是不一样的是,他返回的是一个原始对象

let person = reactive({name:’tony’,age:18})

// 原始对象

let rawPerson = toRaw(person)

而markRaw的话,则是标记一个对象,使其永远不会变为响应式的

最常见的就是在使用第三方类库的时候,标记一个对象,使其不会变为响应式。

let citys = markRaw([

{id:’asdda01′,name:’北京’},

{id:’asdda02′,name:’上海’},

{id:’asdda03′,name:’天津’},

{id:’asdda04′,name:’重庆’}

])

// 根据原始对象citys去创建响应式对象citys2 —— 创建失败,因为citys被markRaw标记了

let citys2 = reactive(citys)

这样在利用reactive创建对象citys2的时候,就会出现创建失败的问题

customRef,

用于自定义一个Ref标签,可以自定义对原数据的跟踪和更新的触发逻辑

其使用比较复杂

这里我们演示下首先我们需要引入这个标签

import { customRef } from “vue”;

而对于这个函数,如果希望使用它的话,需要在其中实现两个接口

get()和set()

并且搭配着两个函数进行使用

track() 和trigger()

track() 提示持续追踪,trigger() 负责进行追踪

那么综合起来,我们可以实现一个简单的ref效果,代码如下

let initValue = “hello”

let msg = customRef((track,trigger)=>{

return {

// get何时调用?—— msg被读取时

get(){

track() //告诉Vue数据msg很重要,你要对msg进行持续关注,一旦msg变化就去更新

return initValue

},

// set何时调用?—— msg被修改时

set(value){

initValue = value

trigger() //通知Vue一下数据msg变化了

}

}

})

其使用起来和标准的ref一模一样

但是除此之外,我们还可以进行增强版的使用,比如使用customRef来要求数据在变更的一秒后才会体现在页面之上。

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);

}

}

})

Teleport

其作用是指定当前组件,需要在页面上依赖哪个父类组件,可能文字描述有点贫瘠,我们直接看下代码。

比如我们首先有一个外部的组件

<template>

<div class=”outer”>

<h2>我是App组件</h2>

<img src=”http://www.atguigu.com/images/index_new/logo.png” alt=””>

<br>

<Modal/>

</div>

</template>

在其中我们声明了使用一个子组件 Modal

在Modal之中,我们也存在着内容

但是我们希望这个类的内容可以根据页面的大小提交,而不是父类的class进行调节。在这个时候就可以使用teleport进行调节

teleport to来指定依赖于上级哪个组件

<template>

<button @click=”isShow = true”>展示弹窗</button>

<teleport to=’body’>

<div class=”modal” v-show=”isShow”>

<h2>我是弹窗的标题</h2>

<p>我是弹窗的内容</p>

<button @click=”isShow = false”>关闭弹窗</button>

</div>

</teleport>

</template>

通过teleport,来指定其依赖于body

其次是Suspense组件

如果引用了一个子组件,那么子组件很有可能会在setup的时候异步渲染一些额外内容,对于这种情况,直接引用会出现渲染问题

对此,引入了suspense,其第一可以等待渲染完成再展示子组件,第二可以在等待渲染的时候展示一些其他的内容。

比如我们有一个子类

<template>

<div class=”child”>

<h2>我是Child组件</h2>

<h3>当前求和为:{{ sum }}</h3>

</div>

</template>

<script setup lang=”ts”>

import {ref} from ‘vue’

import axios from ‘axios’

let sum = ref(0)

let {data:{content}} = await axios.get(‘https://api.uomg.com/api/rand.qinghua?format=json’)

console.log(content)

</script>

这样子组件之中存在着异步的请求,我们无法直接在父组件之中引用

如果希望在其中进行使用的话,那么可以考虑使用suspense

<template>

<div class=”app”>

<h2>我是App组件</h2>

<Suspense>

<template v-slot:default>

<Child/>

</template>

<!– <template v-slot:fallback> –>

<!– <h2>加载中……</h2> –>

<!– </template> –>

</Suspense>

</div>

</template>

Suspense作为一个组件,类似slot的使用

内部还维护了两个不同的具名插槽

v-slot:default是加载好之后的展示

v-slot:fallback是加载中的展示

除此之外,还有一些组件

– `app.component`

– `app.config`

– `app.directive`

– `app.mount`

– `app.unmount`

– `app.use`

会在未来开发过程中用到。

例如

app.component 可以声明一个全局组件,全局都可以使用。

app.component(‘Hello’,Hello)

app.config.globalProperties.x

来声明全局的变量信息

app.directive(‘beauty’,(element,{value})=>{

element.innerText += value

element.style.color = ‘green’

element.style.backgroundColor = ‘yellow’

})

声明全局的函数

发表评论

邮箱地址不会被公开。 必填项已用*标注