slot vue 用法專題及常見問題 - CSDN

2020-12-25 CSDN技術社區

摘要: 理解Vue插槽。

Fundebug經授權轉載,版權歸原作者所有。

為了保證的可讀性,本文採用意譯而非直譯。

最近發布不久的Vue 2.6,使用插槽的語法變得更加簡潔。 對插槽的這種改變讓我對發現插槽的潛在功能感興趣,以便為我們基於Vue的項目提供可重用性,新功能和更清晰的可讀性。 真正有能力的插槽是什麼?

如果你是Vue的新手,或者還沒有看到2.6版的變化,請繼續閱讀。也許學習插槽的最佳資源是Vue自己的文檔,但是我將在這裡給出一個綱要。

想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等著你!

插槽是什麼?

插槽是Vue組件的一種機制,它允許你以一種不同於嚴格的父子關係的方式組合組件。插槽為你提供了一個將內容放置到新位置或使組件更通用的出口。從一個簡單的例子開始:

// frame.vue

這個組件最外層是一個div。假設div的存在是為了圍繞其內容創建一個樣式框架。這個組件可以通用地用於將框架包圍在wq你想要的任何內容上,來看看它是怎麼用的。這裡的frame組件指的是我們剛才做的組件。

// app.vue

在開始和結束frame標記之間的內容將插入到插槽所在的frame組件中,替換slot標記。這是最基本的方法。還可以簡單地通過填充指定要放入槽中的默認內容

// frame.vue

所以現在如果我們這樣使用它:

// app.vue

「如果這裡沒有指定任何內容,這就是默認內容」是默認內容,但是如果像以前那樣使用它,默認文本將被img標記覆蓋。

多個/命名的插槽

可以向組件添加多個插槽,但是如果這樣做了,那麼除了其中一個之外,其他所有插槽都需要有名稱。如果有一個沒有名稱的槽,它就是默認槽。下面是如何創建多個插槽:

// titled-frame.vue

Title

如果這裡沒有指定任何內容,這就是默認內容

我們保留了相同的默認槽,但這次我們添加了一個名為header的槽,可以在其中輸入標題,用法如下:

// app.vue

My Image’s Title

就像之前一樣,如果我們想將內容添加到默認槽中,只需將其直接放在titled-frame組件中。但是,要將內容添加到命名槽中,我們需要用v-slot指令將代碼包裹在在template標記中。在v-slot之後添加冒號(:),然後寫出要傳遞內容的slot的名稱。

注意,v-slot是Vue 2.6的新版本,所以如果你使用的是舊版本,則需要閱讀關於不推薦的slot語法的文檔。

作用域插槽

還需要知道的另一件事是插槽可以將數據/函數傳遞給他們的孩子。 為了證明這一點,我們需要一個完全不同的帶有插槽的示例組件:創建一個組件,該組件將當前用戶的數據提供給其插槽:

// current-user.vue

{{ user.lastName }}

export default {

data () {

return {

user: ...

}

}

}

該組件有一個名為user的屬性,其中包含關於用戶的詳細信息。默認情況下,組件顯示用戶的姓,但請注意,它使用v-bind將用戶數據綁定到slot。這樣,我們就可以使用這個組件向它的後代提供用戶數據

// app.vue

{{ slotProps.user.firstName }}

為了訪問傳遞給slot的數據,我們使用v-slot指令的值指定作用域變量的名稱。

這裡有幾點需要注意:

我們指定了default的名稱,但是不需要為默認槽指定名稱。相反,我們可以使用v-slot="slotProps"。

不需要使用slotProps作為名稱,可以隨便叫它什麼。

如果只使用默認槽,可以跳過內部template標記,直接將v-slot指令放到當前current-user上。

可以使用對象解構來創建對作用域插槽數據的直接引用,而不是使用單個變量名。換句話說,可以使用v-slot="{user}"代替v-slot="slotProps",然後可以直接使用user而不是slotProps.user。

所以,上面的例子可以這樣重寫

// app.vue

{{ user.firstName }}

還有幾點要記住:

可以使用v-bind指令綁定多個值。

也可以將函數傳遞到作用域槽。許多庫使用它來提供可重用的函數組件。

v-slot 的別名是#。因此,可以用#header="data" 來代替 v-slot:header="data"。還可以使用 #header來代替 v-slot:header(前提:不是作用域插槽時)。對於默認插槽,在使用別名時需要指定默認名稱。換句話說,需要這樣寫 #default="data" 而不是#="data"。

可以從文檔中了解更多的細節,但這足以幫助你理解在本文剩下部分中討論的內容。

你能用插槽做什麼?

插槽不是為了一個目的而構建的,或者至少如果它們是,它們已經超越了最初的意圖,成為做許多不同事物的強大工具。

可重用的模式

組件總是被設計為可重用的,但是某些模式對於使用單個「普通」組件來實施是不切實際的,因為為了自定義它,需要的props 數量可能過多或者需要通過props傳遞大部分內容或其它組件。

插槽可用包裹外部的HTML標籤或者組件,並允許其他HTML或組件放在具名插槽對應名稱的插槽上。

對於的第一個例子,從簡單的東西開始:一個按鈕。假設咱們的團隊正在使用 Bootstrap。使用Bootstrap,按鈕通常與基本的「btn」類和指定顏色的類綁定在一起,比如「btn-primary」。你還可以添加size類,比如'btn-lg'。

為了簡單起見,現在讓我們假設你的應用使用btn、btn-primary和btn-lg。你不希望總是必須在按鈕上寫下這三個類,或者你不相信新手會記得寫下這三個類。

在這種情況下,可以創建一個自動包含所有這三個類的組件,但是如何允許自定義內容? prop 不實用,因為允許按鈕包含各種HTML,因此我們應該使用一個插槽。

Click Me!

現在我們可以在任何地方使用它,無論你想要什麼內容

我是小智!

當然,你可以選擇比按鈕更大的東西。 堅持使用Bootstrap,讓我們看一個模態:

現在,使用它:

大家最棒!

大家加油

大家好樣的!

上述類型的插槽用例顯然非常有用,但它可以做得更多。

代碼部署後可能存在的BUG沒法實時知道,事後為了解決這些BUG,花了大量的時間進行log 調試,這邊順便給大家推薦一個好用的BUG監控工具 Fundebug。

復用函數

Vue組件並不完全是關於HTML和CSS的。它們是用JavaScript構建的,所以也是關於函數的。插槽對於一次性創建函數並在多個地方使用功能非常有用。讓我們回到模態示例並添加一個關閉模態的函數

export default {

//...

methods: {

closeModal () {

// 關閉對話框時,需要做的事情

}

}

}

當使用此組件時,可以向footer添加一個可以關閉模態的按鈕。 通常,在Bootstrap模式的情況下,可以將data-dismiss =「modal」添加到按鈕來進行關閉。

但我們希望隱藏Bootstrap 特定的東西。 所以我們傳遞給他們一個他們可以調用的函數,這樣使用者就不會知道我們有使用 Bootstrap 的東西。

Awesome Interruption!

大家加油!

點我可以關閉煩人的對話框

無渲染組件

最後,可以利用你所知道的關於使用插槽來傳遞可重用函數的知識,並剝離所有HTML,只使用插槽。這就是無渲染組件的本質:一個只提供函數而不包含任何HTML的組件。

使組件真正無渲染可能有點棘手,因為需要編寫render函數而不是使用模板來消除對根元素的依賴,但它可能並不總是必要的。 來看看一個先使用模板的簡單示例:

.fade-enter-active,

.fade-leave-active {

transition: opacity 0.3s;

}

.fade-enter, .fade-leave-to {

opacity: 0;

}

這是一個無渲染組件的奇怪例子,因為它甚至沒有任何JavaScript。這主要是因為我們正在創建一個內置無渲染函數的預配置可重用版本:transition。

是的,Vue有內置的無渲染組件。這個特殊的例子取自Cristi Jora的一篇關於可重用transition的文章,展示了一種創建無渲染組件的簡單方法,該組件可以標準化整個應用程式中使用的 transition。

對於我們的另一個示例,我們將創建一個組件來處理切換 Promise 的不同狀態中顯示的內容: pending、resolved 和 failed。這是一種常見的模式,雖然它不需要很多代碼,但是如果沒有為了可重用性而提取邏輯,它會使很多組件變得混亂。

export default {

props: {

promise: Promise

},

data: () => ({

resolved: false,

data: null,

error: null

}),

watch: {

promise: {

handler (promise) {

this.resolved = false

this.error = null

if (!promise) {

this.data = null

return

}

promise.then(data => {

this.data = data

this.resolved = true

})

.catch(err => {

this.error = err

this.resolved = true

})

},

immediate: true

}

}

}

這是怎麼回事,小老弟?首先,請注意,該組件接收一個Promise 類型參數。在watch部分中,監聽promise的變化,當promise發生變化時,清除狀態,然後調用 then 並 catch promise,當 promise 成功完成或失敗時更新狀態。

然後,在模板中,我們根據狀態顯示一個不同的槽。請注意,我們沒有保持它真正的無渲染,因為我們需要一個根元素來使用模板。我們還將data和error傳遞到相關的插槽範圍。

Resolved: {{ data }}

Rejected: {{ error }}

請求中...

...

我們將somePromise傳遞給無渲染組件。 然後等待它完成,對於 pending 的插槽,顯示「請求中...」。 如果成功,顯示「Resolved:對應的值」。 如果失敗,顯示「已Rejected:失敗的原因」。 現在我們不再需要跟蹤此組件中的promise的狀態,因為該部分被拉出到它自己的可重用組件中。

那麼,我們可以做些什麼來繞過promised.vue中的插槽? 要刪除它,我們需要刪除template部分並向我們的組件添加render函數:

render () {

if (this.error) {

return this.$scopedSlots['rejected']({error: this.error})

}

if (this.resolved) {

return this.$scopedSlots['resolved']({data: this.data})

}

return this.$scopedSlots['pending']()

}

這裡沒有什麼太複雜的。我們只是使用一些if塊來查找狀態,然後返回正確的作用域slot(通過this.$ scopedslot ['SLOTNAME'](…)),並將相關數據傳遞到slot作用域。當你不使用模板時,可以跳過使用.vue文件擴展名,方法是將JavaScript從script標記中提取出來,然後將其放入.js文件中。在編譯這些Vue文件時,這應該會給你帶來非常小的性能提升。

總結

Vue的插槽將基於組件的開發提升到了一個全新的水平,雖然本文已經展示了許多可以使用插槽的好方法,但還有更多的插槽。歡迎留言討論。

代碼部署後可能存在的BUG沒法實時知道,事後為了解決這些BUG,花了大量的時間進行log 調試,這邊順便給大家推薦一個好用的BUG監控工具 Fundebug。

關於Fundebug

Fundebug專注於JavaScript、微信小程序、微信小遊戲、支付寶小程序、React Native、Node.js和Java線上應用實時BUG監控。 自從2016年雙十一正式上線,Fundebug累計處理了10億+錯誤事件,付費客戶有陽光保險、核桃編程、荔枝FM、掌門1對1、微脈、青團社等眾多品牌企業。歡迎大家免費試用!

相關焦點

  • slot vue 具名專題及常見問題 - CSDN
    vue的slot1、什麼是slotslot是插槽,插即是可以插入,槽就是坑,即是可以再代碼中插入如果子組件模板中不包含插口,那麼父組件的內容將會被丟棄。當子組件模板中有一個麼有屬性的插槽時,父組件傳入的整個內容片段,將插入到插槽所在的dom的位置,並替換掉插槽標籤本身。
  • slot-scope vue - CSDN
    前言vue 插槽,目前到3.0有2種方式,第一種,在2.6之前使用的是slot 和 slot-scpe 2.6後已被官方廢棄,但在2.x版本仍被支持,第二種是vue 在2.6版本後更新的新指令 v-slot 來替代slot 和slot-scpe那麼什麼是插槽呢,作用又是什麼插槽,簡單說,插槽就是杯子
  • template標籤 vue 作用專題及常見問題 - CSDN
    > <slot name='header'></slot> </header> <main> <slot></slot> </main> <footer> <
  • a標籤 href vue專題及常見問題 - CSDN
    插槽的指令為v-slot,它目前取代了slot和slot-scope,插槽內容,vue實例一套內容分發的api,將slot元素作為承載分發內容的出口。什麼是插槽,它是vue提出的一個概念,插槽用於決定將所攜帶的內容,插入到指定的某個位置,使得模塊分塊,具有模塊化特質。插槽怎麼用?
  • 如何寫一個vue組件專題及常見問題 - CSDN
    轉自:https://www.cnblogs.com/pengchenggang/p/10880437.html如何寫好一個vue組件一個適用性良好的組件,一種是可配置項很多,另一種就是容易覆寫,從而擴展功能Vue 組件的 API 來自三部分——prop、事件和插槽:prop 允許外部環境傳遞數據給組件event 允許從組件內觸發外部環境的副作用slot
  • slot命名 vue - CSDN
    gt;<slot></slot><slot  style=」color:blue;」 >這是在slot上添加了樣式</slot><slot  name=」mySlot」>這是擁有命名的slot的默認內容</slot></div></template>會輸出:
  • vue中的slot插槽怎麼用?
    vue中的slot插槽怎麼用?當我們利用組件實現項目需求時,我們有時候會希望像html中其他標籤那樣,可以在使用組件時插入我們的自定義內容。html代碼這個時候我們需要使用vue提供的slot插槽來解決。
  • material vue專題及常見問題 - CSDN
    Vue Materialhttps://vuematerial.io/https://vuematerial.io/getting-started/IntroductionVue Material is the best integration between
  • ref vue 獲取文本專題及常見問題 - CSDN
    ref的官網介紹https://cn.vuejs.org/v2/api/#ref需求在普通的js操作中,一般都是直接操作dom元素,但是對於Vue.js框架來說,一般是不允許直接操作dom元素的。那麼其實Vue.js框架提供了ref獲取dom元素,以及組件引用。
  • c++ 槽函數專題及常見問題 - CSDN
    1 called" << std::endl;}void slots2(int a) {std::cout << "slot 2 called " << a << std::endl;}void slots3(int a) {std::cout << "slot 3 called " << a << std::endl
  • 2020大廠前端面試之vue專題
    O(n) 複雜度的問題(只比較同級不考慮跨級問題) 在前端當中, 你很少會跨越層級地移動Dom元素。}, slot: "footer" }, [_v("vue")])]) } */ const VueTemplateCompiler = require('vue-template-compiler'); let ele = VueTemplateCompiler.compile(`<div><slot name="header"><
  • Vue 開發必須知道的 36 個技巧
    前言Vue基本用法很容易上手,但是有很多優化的寫法你就不一定知道了,本文從列舉了 36 個 vue 開發技巧;後續 Vue 3.x 出來後持續更新.$dispatch或mapActions       訪問modules:模塊,如果狀態過多,可以拆分成模塊,最後在入口通過...解構引入3.4 和listeners2.4.0 新增這兩個是不常用屬性,但是高級用法很常見;1.場景如果父傳子有很多值那麼在子組件需要定義多個解決attrs獲取子傳父中未在
  • 35道常見的前端vue面試題
    這篇文章我們一起來聊一聊VUE及全家桶的常見面試問題。1、請講述下VUE的MVVM的理解?MVVM 是 Model-View-ViewModel的縮寫,即將數據模型與數據表現層通過數據驅動進行分離,從而只需要關係數據模型的開發,而不需要考慮頁面的表現,具體說來如下:Model代表數據模型:主要用於定義數據和操作的業務邏輯。
  • 信號與槽專題及常見問題 - CSDN
    槽(slot)槽:用於接收信號。槽只是普通的對象成員函數。一個槽並不知道是否有任何信號與自己相連接。而且對象並不了解具體的通信機制。槽是普通的 C++ 成員函數,可以被正常調用,它們唯一的特殊性就是很多信號可以與其相關聯。當與其關聯的信號被發射時,這個槽就會被調用。槽可以有參數,但槽的參數不能有預設值。
  • h5 vue 表格專題及常見問題 - CSDN
    #前言最近做移動端的h5項目,要做一個可配置表頭的複雜表格,網上找了很久也沒什麼好方法,結合網上的一些例子,在此做一了一個完整的vue版的例子。#效果無圖無真相,先上最終效果圖再說 。i = 0; i < frozenCrosses.length; i++) { frozenCrosses[i].style.transform = 'translate(0px, 0px) translateZ(0px)'; } }, 0);}###第三步:使用引用前面的自己封裝的iscrollTable.js,用到的table.vue
  • java 信號與槽專題及常見問題 - CSDN
    QT信號/槽在我的理解中,QT和Android都是類似的開發框架,都是由開發團隊封裝了各式各樣的接口和數據結構.將一些問題的解決方法簡單化 比如QT中將線程封裝為QThread,派生類通過重寫run方法來將代碼投入到新的線程執行,而同樣的Android中的線程是Java自帶的Thread
  • redis 槽是什麼專題及常見問題 - CSDN
    則保存在第2個節點上,餘數為0則保存在第3個節點,這樣可以保證數據被打散,同時保證數據分布的比較均勻哈希分布方式分為三個分區方式:2.3.1 節點取餘分區比如有100個數據,對每個數據進行hash運算之後,與節點數進行取餘運算,根據餘數不同保存在不同的節點上節點取餘方式是非常簡單的一種分區方式節點取餘分區方式有一個問題
  • cluster redis 分槽專題及常見問題 - CSDN
    為了使得集群能夠水平擴展,首要解決的問題就是如何將整個數據集按照一定的規則分配到多個節點上,常用的數據分片的方法有:範圍分片,哈希分片,一致性哈希算法和虛擬哈希槽等。範圍分片假設數據集是有序,將順序相臨近的數據放在一起,可以很好的支持遍歷操作。範圍分片的缺點是面對順序寫時,會存在熱點。
  • Vue常見面試題攻略
    slot是什麼?有什麼作用?原理是什麼?slot又名插槽,是Vue的內容分發機制,組件內部的模板引擎使用slot元素作為承載分發內容的出口。插槽slot是子組件的一個模板標籤元素,而這一個標籤元素是否顯示,以及怎麼顯示是由父組件決定的。
  • vue中組件的使用(下)
    html代碼js代碼針對$emit的用法組件插槽在應用組件的時候,我們可以利用vue自定義的<slot>標籤,為組件內部插入自定義內容,就像<h1>那。比如我們想在使用一個叫做<input-component>的組件時候插入一個提示信息內容「this is a component about enrolment.」我們只需要通過以下兩個簡單的步驟就能夠達到目的:在組件模板中想要插入自定義內容的地方使用<slot>標籤(內部可以自帶默認內容)