vue3中的一些API
shallowRef ( ) 和shallowReactive ( )
shallowRef (淺層響應式)
1.作用:創建一個響應式數據,但只對頂層屬性進行響應式處理。
2.用法:
const original=ref(...)
const original2=shallowRef(original)
3.特點:只跟蹤引用值的變化,不關心值內部的屬性變化。
shallowReactive (淺層響應式)
1.作用:創建一個淺層響應式對象,只會使對象的最頂層屬性變成響應式的,對象內部的嵌套屬性則不會變成響應式的
2.用法:
const myObj = reactive({...})
const myObj2= shallowReactive({myObj})
3.特點:對象的頂層屬性是響應式的,但嵌套對象的屬性不是。
總結
通過使用shallowRef()和shallowReactive()來繞開深度響應。淺層式API創建的狀態只在其頂層是響應式的,對所有深層的對象不會做任何處理,避免了對每一個內部屬性做響應式所帶來的性能成本,這使得屬性的訪問變得更快,可提升性能。
readonly( ) 和 shallowReadonly( )
readonly
1.作用:用于創建一個對象的深只讀副本。 (不可修改)
2.用法:
const original = reactive({...})
const original2 = readonly({ original })
3.特點:
對象的所有嵌套屬性都將變為只讀。
任何嘗試修改這個對象的操作都會被阻止(在開發模式下,還會在控制臺中發出警告)。
4.應用場景:
創建不可變的狀態快照。
保護全局狀態或配置不被修改。
shallowReadonly
1.作用:與readonly類似,但只作用于對象的頂層屬性。
2.用法:
const original = reactive({...})
const original2 = shallowReadonly({ original })
3.特點:
只將對象的頂層屬性設置為只讀,對象內部的嵌套屬性仍然是可變的。
適用于只需保護對象頂層屬性的場景。
toRaw( ) 和 markRaw( )
toRaw
1.作用:用于獲取一個響應式對象的原始對象。
2.toRaw返回的對象不再是響應式的,不會觸發視圖的更新。
場景:
在需要將響應式對象傳遞給非vue的庫或外部系統時,使用toRaw可以確保他們收到的是普通對象
用法:
const original = reactive({...})
//響應式數據
const original2 = toRaw({ original })
//原始數據
markRaw
1.作用:標記一個對象,使其永遠不會變成響應式的。
例如:第三方庫:mockjs
const mockJs = markRaw({mockjs})
const mockJs2 = reactive({ mockJs })
//mockJs2不是響應式數據
customRef
重點注意:track,trigger
<template><h2>信息是:{{msg}}</h2><input type="text" v-model="msg"><!-- 雙向綁定 獲取響應式數據 -->
</template><script setup lang="ts" name="App">import {ref} from "vue"const msg=ref("你好")
</script>
結果:
<template><h2>信息是:{{msg}}</h2><input type="text" v-model="msg"><!-- 雙向綁定 獲取響應式數據 -->
</template><script setup lang="ts" name="App">import {customRef,ref} from "vue"// const msg=ref("你好") //使用ref只能實現基本的響應式數據變化// 要求:表單中數據變化后1秒之后,h2中的數據發生改變// 這時用ref來做是不能實現的,所以使用自定義響應式:customRef (customRef是一個函數)let initValue=""let timerconst msg=customRef((track,trigger)=>{ //回調函數里有兩個參數:track(跟蹤)和trigger(觸發)return {get(){ //讀取msg時調用get()track() //告訴vue數據很重要,需要持續關注,一旦有變化就要更新 (跟蹤)return initValue},set(value){ //msg發生變化時調用set()clearTimeout(timer) //防止重復開啟定時器timer=setTimeout(()=>{initValue=valuetrigger() //通知vue數據改變},1000)}}})
</script>
封裝自定義響應式數據:
App.vue:
<template><h2>信息是:{{msg}}</h2><input type="text" v-model="msg"><!-- 雙向綁定 獲取響應式數據 -->
</template><script setup lang="ts" name="App">import {customRef,ref} from "vue"// const msg=ref("你好") //使用ref只能實現基本的響應式數據變化// 要求:表單中數據變化后1秒之后,h2中的數據發生改變// 這時用ref來做是不能實現的,所以使用自定義響應式:customRef (customRef是一個函數)import useMsgRef from "./useMsgRef";const {msg}=useMsgRef("你好啊",2000) //傳入兩個參數
</script>
useMsgRef.ts:
// 封裝自定義ref
import {customRef} from "vue"export default function(initValue:string,delay:number){ //注意這里的參數let timerconst msg=customRef((track,trigger)=>{ //回調函數里有兩個參數:track(跟蹤)和trigger(觸發)return {get(){ //讀取msg時調用get()track() //告訴vue數據很重要,需要持續關注,一旦有變化就要更新 (跟蹤)return initValue},set(value){ //msg發生變化時調用set()clearTimeout(timer) //防止重復開啟定時器timer=setTimeout(()=>{initValue=valuetrigger() //通知vue數據改變},delay)}}})return {msg}}
Teleport
作用:將組件html結構移動到指定位置的技術
ModalPage.vue:
<template><div class="modal"><h2>我是ModalPage組件</h2><button @click="isShow=true">展開彈框</button><teleport to="body"> <!-- <teleport to=".app"> --><div class="content" v-show="isShow"><h2>彈框標題</h2><h2>彈框內容</h2><button @click="isShow=false">關閉彈框</button></div></teleport></div>
</template><script setup name="ModalPage">
import {ref} from "vue"
const isShow=ref(false)
</script><style scoped>.modal {width: 600px;height: 200px;background-color: pink;box-shadow: 0 0 10px;border-radius: 5px;margin-top: 50px;}.content {background-color: skyblue;width: 320px;height: 200px;text-align: center;position:fixed;/* position:fixed;以視口為參照物 */top:50%;left:50%;transform: translate(-50%,-50%);}
</style>
App.vue:
<template><div class="app"><h2>我是App組件</h2><img src="./assets/images/11.png"><ModalPage/></div>
</template><script setup lang="ts" name="App">import ModalPage from "./components/ModalPage.vue"
</script><style scoped>.app {width: 800px;height: 600px;background-color: #ddd;border-radius: 10px;box-shadow: 0 0 10px;}img {width: 200px;height: 130px;background-size: cover;/* 對于以前: *//* 當不加css樣式中的filter濾鏡時,子組件的position:fixed是可以根據視口來調整大小 *//* 但當加上這個樣式之后,position:fixed失效 */filter: saturate(200%);/* saturate是飽和度的意思 *//* 解決方法:在模板中給需要根據視口調整大小的內容外包上<teleport>標簽 并加上to屬性(具體見子組件) */}
</style>
Suspense
等待異步組件時渲染一些額外內容,讓應用有更好的用戶體驗使用步驟:
- 異步引入組件
- 使用Suspense包裹組件,并配置好default與fallback
App.vue:
<template><div class="app"><h2>我是App組件</h2><!-- 當子組件里要處理異步任務,網速慢時想要在頁面呈現一些東西就可以使用Suspense --><Suspense><template v-slot:default><ModalPage/></template></Suspense><!-- 當網速慢,頁面沒加載出來時可以顯示的內容 --><Suspense><template v-slot:fallback><h2>loading...</h2></template></Suspense></div>
</template><script setup lang="ts" name="App">import ModalPage from "./components/ModalPage.vue"
</script>
ModalPage.vue:
<template><div class="modal"><h2>我是ModalPage組件</h2> </div>
</template><script setup name="ModalPage">
import {ref} from "vue"
import axios from "axios"
// 異步獲取數據
let msg=await axios.get("https://api.uomg.com/api/rand.qinghua?format=json")
console.log(msg)
</script>