一、什麼是shallowRef函數
shallowRef函數是Vue 3中一個響應式函數,它可以將傳入的非響應式對象轉換為響應式對象,並且可以讓這個對象成為響應式狀態的根源,當對象發生變化時,會讓所有引用該對象的組件或者函數重新渲染。
shallowRef函數與ref函數的不同之處在於它僅對對象的第一層進行響應式處理,第二層及以下的屬性變化將不會觸發更新。這種特性常用於性能優化。
import { shallowRef } from 'vue'
const obj = { name: 'Tom', age: 20 }
const objRef = shallowRef(obj)
console.log(objRef.value.name) // Tom
objRef.value.name = 'Jerry' // 觸發組件渲染
二、shallowRef函數的使用場景
使用shallowRef函數一般意味着你需要用到對象的第一層屬性,並且這些屬性的變化需要觸發組件更新。常見的使用場景有:
1、對象屬性在模板中使用
當對象的第一層屬性在組件模板中展示時,常用shallowRef函數將對象轉換為響應式對象,這樣在屬性發生變化時能夠觸發組件的重新渲染。
<template>
<div>
<p>Name: {{ user.name }}</p>
<p>Age: {{ user.age }}</p>
</div>
</template>
<script>
import { shallowRef } from 'vue'
export default {
setup() {
const user = shallowRef({ name: 'Tom', age: 20 })
return { user }
}
}
</script>
2、對象作為函數參數傳遞
當對象作為函數參數傳遞時,常用shallowRef函數將對象轉換為響應式對象,這樣在函數內部修改對象的屬性時能夠觸發組件的重新渲染。
<template>
<div>
<p>Name: {{ user.name }}</p>
<p>Age: {{ user.age }}</p>
<button @click="updateUser">Update</button>
</div>
</template>
<script>
import { shallowRef } from 'vue'
export default {
setup() {
const user = shallowRef({ name: 'Tom', age: 20 })
function updateUser() {
// 修改對象屬性,觸發組件重新渲染
user.value.name = 'Jerry'
user.value.age = 21
}
return { user, updateUser }
}
}
</script>
三、shallowRef函數的注意事項
1、使用shallowRef函數的對象不應該是一個響應式對象
當使用shallowRef函數將一個已經是響應式對象的對象再次轉換為響應式對象時,會出現以下錯誤:
const obj = reactive({ name: 'Tom', age: 20 })
const objRef = shallowRef(obj) // 報錯:不能將已經是響應式的對象轉換為響應式對象
2、不要濫用shallowRef函數
由於shallowRef函數的特性,只會對對象的第一層進行響應式處理,當對象的更深層次的屬性變化時,不會觸發組件重新渲染,容易出現更新不及時的情況。因此,在使用shallowRef函數時,需慎重考慮對象的屬性結構,以免濫用。
3、使用shallowRef函數的對象不要包含函數屬性
當對象包含函數屬性時,使用shallowRef函數將會把函數當做對象的屬性進行處理,而函數屬性本身不應該被響應式處理。
const obj = { name: 'Tom', sayHello: function() { console.log('Hello!') } }
const objRef = shallowRef(obj) // 函數屬性不應該被響應式處理
四、shallowRef函數的優化應用
shallowRef函數由於只會對對象的第一層進行響應式處理,可以用於優化組件性能。通常情況下,當一個對象的第一層屬性發生變化時,組件需要重新渲染,而對象深層次的屬性發生變化時,渲染沒有必要,因此使用shallowRef函數可以有效避免不必要的組件渲染,提高應用程序性能。
例如,在Vue 3中使用shallowRef函數優化一個包含子組件的列表時:
<template>
<div>
<div v-for="item in list" :key="item.id">
<my-component :item="item" :is-active="item.isActive" />
<button @click="update(item)">Update</button>
</div>
</div>
</template>
<script>
import { shallowRef } from 'vue'
import MyComponent from './MyComponent.vue'
export default {
components: { MyComponent },
setup() {
const list = shallowRef([
{ id: 1, name: 'Item 1', isActive: false },
{ id: 2, name: 'Item 2', isActive: false },
{ id: 3, name: 'Item 3', isActive: false }
])
function update(item) {
item.isActive = !item.isActive // 只更新對象的第一層屬性,避免不必要的渲染
}
return { list, update }
}
}
</script>
五、總結
通過本文的介紹,我們對Vue 3的shallowRef函數有了更深入的了解。shallowRef函數提供了性能優化的方案,但也存在一些需要注意的問題。在實際使用時,需要根據對象的屬性結構以及業務需求進行慎重考慮,避免濫用和出現不必要的問題。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/162644.html