成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何解決--在渲染函數之外調用插槽的問題

開發 前端
在開發Vue組件時,需要訪問插槽函數的情況并不常見,但如果你需要這樣做,我希望上面的解決方案能為你節省一些時間。

如果你是用 Vue 來開發項目的,那么,你曾經有可能訪問 slot.default() 遇到如下問題:

Slot "default" invoked outside of the render function:
this will not track dependencies used in the slot.
Invoke the slot function inside the render function instead.

本文本中,將會解釋這個錯誤背后的原因以及如何解決這個問題。

插槽的調用需要發生在渲染函數或模板中。要抑制這個錯誤,我們只需要把代碼移到一個計算的屬性或從模板或渲染函數中調用的方法中。

“this will not track dependencies used in the slot”  指的是什么?

錯誤信息解釋了問題產生的本質原因,但這個提示不是很清晰,無法幫助我們界定問題的本質。下面,我們來詳細介紹下錯誤背后的原因產生。

this will not track dependencies used in the slot.

經過一些調查,我做了一個可復現的代碼,并理解了在渲染函數之外使用slots.default()語法的含義。為了理解這個問題,我們先復習一下 Vue 的響應式原理。

Vue 的響應式性系統允許我們聲明屬性、數據和計算屬性,而不需要跟蹤它們的變化。響應式性系統在幕后工作,確保我們的變量始終是最新的。

在Vue框架內,最常見的響應式特征的情況是使用 computed:

計算屬性指的是一個變量,它可以被用來以有效和響應式的方式修改和操作你的組件中的數據和屬性。

計算屬性的一個簡單例子是博客片段,我們把一篇完整的博客文章作為屬性傳遞,并把它截斷成一定數量的字符。另一個更常見的例子是一個簡單的變量,用來定義一個按鈕的文本,根據當前的狀態 "顯示 "或 "隱藏"。

舉例來說,在 "expanded"的值被改變之前,下面的屬性將永遠不會再被運行。

const buttonText = computed( () => {
return expanded.value ? 'Show less' : 'Show more';
});

除非 expanded  的值發生變化,否則上述方法不會再被觸發。Vue 在幕后所做的觀察 expanded 變量的工作就是所謂的 "跟蹤依賴性"。

你可能已經意識到了,"跟蹤依賴" 這幾個字和Vue框架在試圖訪問插槽時產生的錯誤中提到的一樣。事實上,這個錯誤是為了告訴我們,在渲染函數之外使用slots.default()的語法,會使變量失去響應性,因此它不會 "跟蹤" 任何可能影響它的變化。

拿上面的例子來說,失去依賴關系的跟蹤將意味著無論 expanded 的值是多少,按鈕都不會改變。

// 下面的代碼只是為了說明問題
// 我們只是假設了一個具有跟蹤依賴性的變量,這也是我們插槽發生的情況
const expanded = ref( false ); //Broken Tracking
console.log(buttonText)
// 輸出 "Show more"
expanded.value = true;
console.log(buttonText)
// 輸出: "Show more" 值沒有沒有改變,因為Vue無法跟蹤 expanded 的變化。

在我們的代碼庫中,未被追蹤的變量不是我們想要的東西,應該要盡量的避免它。

如何確保 Vue 插槽被跟蹤依賴

接下來,我們分析下可以做些什么來確保我們的插槽有一個響應式的跟蹤系統,確保不會更新失敗

通過確保我們的槽調用發生在渲染函數和模板中,問題就可以解決了,正如錯誤信息中提到的那樣。

Invoke the slot function inside the render function

我們現在要介紹兩種不同的情況。第一種是在使用渲染函數時調用插槽函數,第二種是在使用vue單文件組件的<template>部分。

在渲染函數中使用插槽

當在一個有渲染函數的組件中使用插槽時,我們必須確保在渲染函數的 "return"語句中調用插槽函數,而不是在 setup 中。

// 不好
import { h } from 'vue'
export default {
setup( props, { slots } ) {
const defaultSlot = slots.default();
return () => h('div', defaultSlot)
}
}
// 好
import { h } from 'vue'
export default {
setup( props, { slots } ) {
return () => h('div', slots.default())
}
}

在使用單一文件組件(SFC)時使用插槽

如果使用單文件組件并使用 <template> 塊聲明 HTML,你可能會認為不能直接訪問渲染函數,但事實并非如此。

當我第一次遇到這個問題時,我花了一些時間試圖了解如何在渲染函數中移動插槽函數,但在Spa 之后,我想起了 <template>標簽是由編譯器為我們轉化成渲染函數的。

了解 <template> 塊和渲染函數是等價的,對我們定義解決問題的方法有很大幫助。事實上,為了消除警告并確保在我們的組件中跟蹤依賴關系,我們需要確保插槽的調用發生在HTML中(隨后被框架編譯成一個渲染函數)。

舉個例子:

// 缺點 - 如插槽改變,它將不會改變
<template>
<div :class="{ 'style-for-svg': isSvg }">
<slot></slot>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup( props, { slots } ) {
const isSvg = ref( false );
if( slots.default()[0].type === 'svg' ) {
isSvg.value = true;
}
return {
isSvg
}
}
}
</script>
// 優點:插槽改變,跟著變化
<template>
<div :class="{ 'style-for-svg': $slots.default()[0].type === 'svg' }">
<slot></slot>
</div>
</template>
<script>
export default {
setup( ) {
}
}
</script>

解決這個問題是很簡單的。直接在模板中加入函數調用,就可以解決我們的問題了。不幸的是,上面的解決方案代碼不夠簡潔。

那要怎么做呢?使用計算屬性。

在調查過程中,計算屬性也被編譯為渲染函數的一部分,可以用來使代碼更易讀,并且仍然保持變量的響應式。

<template>
<div :class="{ 'style-for-svg': isSvg }">
<slot></slot>
</div>
</template>
<script>
import { computed } from 'vue'
export default {
setup( ) {
const isSvg = computed( () => {
return slots.default()[0].type === 'svg';
} );
return {
isSvg
}
}
}
</script>

總結

在開發Vue組件時,需要訪問插槽函數的情況并不常見,但如果你需要這樣做,我希望上面的解決方案能為你節省一些時間。

責任編輯:姜華 來源: 大遷世界
相關推薦

2022-09-22 08:45:10

Vue組件函數

2012-09-05 11:09:15

SELinux操作系統

2017-10-17 09:21:06

2010-04-29 17:46:31

Oracle死鎖

2019-11-26 14:30:20

Spring循環依賴Java

2024-12-05 09:06:58

2023-07-18 16:05:00

IP地址

2023-11-09 23:31:02

C++函數調用

2009-09-21 17:10:14

struts Hibe

2021-10-20 20:27:55

MySQL死鎖并發

2011-08-29 10:34:00

網絡安全云安全云計算

2023-10-30 18:35:47

MySQL主從延時

2021-06-06 13:05:15

前端跨域CORS

2011-03-23 14:42:47

CPU過度消耗

2010-07-16 13:52:26

telnet漏洞

2017-08-15 17:33:00

青云

2017-07-20 07:30:16

大數據數據互聯網

2024-10-29 16:41:24

SpringBoot跨域Java

2013-05-21 10:49:59

Windows硬件沖突

2017-09-23 22:07:24

深度學習N 體問題GAN
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩毛片免费看 | 日本精品视频一区二区三区四区 | 欧美精品一区在线 | 香蕉大人久久国产成人av | 国产精品一区二区三区在线 | 国产精品欧美日韩 | 瑟瑟免费视频 | 亚洲精品观看 | 一区二区av | 天堂综合 | 国产精品123区 | 日韩在线播放视频 | 国产97在线 | 日韩 | 黄瓜av| 欧美一级片久久 | 久久久成人一区二区免费影院 | 久久久www成人免费无遮挡大片 | 国产高清免费 | 亚洲电影成人 | 国产探花在线精品一区二区 | 日本三级电影在线免费观看 | 日本三级在线 | 久久精品手机视频 | 亚洲另类春色偷拍在线观看 | 狠狠爱免费视频 | 亚洲天堂男人的天堂 | 亚洲美女网站 | 久久三区| 亚洲精品国产成人 | 国产精品日日夜夜 | www亚洲精品 | 在线免费视频一区 | 亚洲色图50p | 国产免费福利在线 | 亚洲一区二区电影在线观看 | 日日夜夜免费精品视频 | 中文字幕 欧美 日韩 | 欧美视频在线播放 | 欧美一区二区三区国产精品 | 久色视频在线观看 | 欧美炮房|