最新文章專(zhuān)題視頻專(zhuān)題問(wèn)答1問(wèn)答10問(wèn)答100問(wèn)答1000問(wèn)答2000關(guān)鍵字專(zhuān)題1關(guān)鍵字專(zhuān)題50關(guān)鍵字專(zhuān)題500關(guān)鍵字專(zhuān)題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專(zhuān)題關(guān)鍵字專(zhuān)題tag2tag3文章專(zhuān)題文章專(zhuān)題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專(zhuān)題3
問(wèn)答文章1 問(wèn)答文章501 問(wèn)答文章1001 問(wèn)答文章1501 問(wèn)答文章2001 問(wèn)答文章2501 問(wèn)答文章3001 問(wèn)答文章3501 問(wèn)答文章4001 問(wèn)答文章4501 問(wèn)答文章5001 問(wèn)答文章5501 問(wèn)答文章6001 問(wèn)答文章6501 問(wèn)答文章7001 問(wèn)答文章7501 問(wèn)答文章8001 問(wèn)答文章8501 問(wèn)答文章9001 問(wèn)答文章9501
當(dāng)前位置: 首頁(yè) - 科技 - 知識(shí)百科 - 正文

詳解vue 2.6 中 slot 的新用法

來(lái)源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 21:53:54
文檔

詳解vue 2.6 中 slot 的新用法

詳解vue 2.6 中 slot 的新用法:最近發(fā)布不久的Vue 2.6,使用插槽的語(yǔ)法變得更加簡(jiǎn)潔。 對(duì)插槽的這種改變讓我對(duì)發(fā)現(xiàn)插槽的潛在功能感興趣,以便為我們基于Vue的項(xiàng)目提供可重用性,新功能和更清晰的可讀性。 真正有能力的插槽是什么? 如果你是Vue的新手,或者還沒(méi)有看到2.6版的變化,請(qǐng)繼續(xù)
推薦度:
導(dǎo)讀詳解vue 2.6 中 slot 的新用法:最近發(fā)布不久的Vue 2.6,使用插槽的語(yǔ)法變得更加簡(jiǎn)潔。 對(duì)插槽的這種改變讓我對(duì)發(fā)現(xiàn)插槽的潛在功能感興趣,以便為我們基于Vue的項(xiàng)目提供可重用性,新功能和更清晰的可讀性。 真正有能力的插槽是什么? 如果你是Vue的新手,或者還沒(méi)有看到2.6版的變化,請(qǐng)繼續(xù)

最近發(fā)布不久的Vue 2.6,使用插槽的語(yǔ)法變得更加簡(jiǎn)潔。 對(duì)插槽的這種改變讓我對(duì)發(fā)現(xiàn)插槽的潛在功能感興趣,以便為我們基于Vue的項(xiàng)目提供可重用性,新功能和更清晰的可讀性。 真正有能力的插槽是什么?

如果你是Vue的新手,或者還沒(méi)有看到2.6版的變化,請(qǐng)繼續(xù)閱讀。也許學(xué)習(xí)插槽的最佳資源是Vue自己的文檔,但是我將在這里給出一個(gè)綱要。

想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客 ,一年百來(lái)篇優(yōu)質(zhì)文章等著你!

插槽是什么?

插槽是Vue組件的一種機(jī)制,它允許你以一種不同于嚴(yán)格的父子關(guān)系的方式組合組件。插槽為你提供了一個(gè)將內(nèi)容放置到新位置或使組件更通用的出口。從一個(gè)簡(jiǎn)單的例子開(kāi)始:

// frame.vue
<template>
 <div class="frame">
 <slot></slot>
 </div>
</template>

這個(gè)組件最外層是一個(gè) div 。假設(shè) div 的存在是為了圍繞其內(nèi)容創(chuàng)建一個(gè)樣式框架。這個(gè)組件可以通用地用于將框架包圍在wq你想要的任何內(nèi)容上,來(lái)看看它是怎么用的。這里的 frame 組件指的是我們剛才做的組件。

// app.vue
<template>
 <frame><img src="an-image.jpg"></frame>
</template>

在開(kāi)始和結(jié)束 frame 標(biāo)記之間的內(nèi)容將插入到插槽所在的 frame 組件中,替換 slot 標(biāo)記。這是最基本的方法。還可以簡(jiǎn)單地通過(guò)填充指定要放入槽中的默認(rèn)內(nèi)容

// frame.vue
<template>
 <div class="frame">
 <slot>如果這里沒(méi)有指定任何內(nèi)容,這就是默認(rèn)內(nèi)容</slot>
 </div>
</template>

所以現(xiàn)在如果我們這樣使用它:

// app.vue
<template>
 <frame />
</template>

“ 如果這里沒(méi)有指定任何內(nèi)容,這就是默認(rèn)內(nèi)容 ”是默認(rèn)內(nèi)容,但是如果像以前那樣使用它,默認(rèn)文本將被 img 標(biāo)記覆蓋。

多個(gè)/命名的插槽

可以向組件添加多個(gè)插槽,但是如果這樣做了,那么除了其中一個(gè)之外,其他所有插槽都需要有名稱(chēng)。如果有一個(gè)沒(méi)有名稱(chēng)的槽,它就是默認(rèn)槽。下面是如何創(chuàng)建多個(gè)插槽:

// titled-frame.vue
<template>
 <div class="frame">
 <header><h2>
 <slot name="header">Title</slot>
 </h2></header>
 <slot>如果這里沒(méi)有指定任何內(nèi)容,這就是默認(rèn)內(nèi)容</slot>
 </div>
</template>

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

// app.vue
<template>
 <titled-frame>
 <template v-slot:header>
 <!-- The code below goes into the header slot -->
 My Image's Title
 </template>
 <!-- The code below goes into the default slot -->
 <img src="an-image.jpg">
 </titled-frame>
</template>

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

注意, v-slot 是 Vue 2.6 的新版本,所以如果你使用的是舊版本,則需要閱讀 關(guān)于不推薦的slot語(yǔ)法的文檔。

作用域插槽

還需要知道的另一件事是插槽可以將數(shù)據(jù)/函數(shù)傳遞給他們的孩子。 為了證明這一點(diǎn),我們需要一個(gè)完全不同的帶有插槽的示例組件:創(chuàng)建一個(gè)組件,該組件將當(dāng)前用戶(hù)的數(shù)據(jù)提供給其插槽:

// current-user.vue
<template>
 <span>
 <slot v-bind:user="user">
 {{ user.lastName }}
 </slot>
 </span>
</template>

<script>
export default {
 data () {
 return {
 user: ...
 }
 }
}
</script>

該組件有一個(gè)名為 user 的屬性,其中包含關(guān)于用戶(hù)的詳細(xì)信息。默認(rèn)情況下,組件顯示用戶(hù)的姓,但請(qǐng)注意,它使用 v-bind 將用戶(hù)數(shù)據(jù)綁定到 slot 。這樣,我們就可以使用這個(gè)組件向它的后代提供用戶(hù)數(shù)據(jù)

// app.vue
<template>
 <current-user>
 <template v-slot:default="slotProps">{{ slotProps.user.firstName }}</template> 
 </current-user>
</template>

為了訪(fǎng)問(wèn)傳遞給 slot 的數(shù)據(jù),我們使用v-slot指令的值指定作用域變量的名稱(chēng)。

這里有幾點(diǎn)需要注意:

  • 我們指定了 default 的名稱(chēng),但是不需要為默認(rèn)槽指定名稱(chēng)。相反,我們可以使用v -slot="slotProps" 。
  • 不需要使用 slotProps 作為名稱(chēng),可以隨便叫它什么。
  • 如果只使用默認(rèn)槽,可以跳過(guò)內(nèi)部 template 標(biāo)記,直接將 v-slot 指令放到當(dāng)前 current-user 上。
  • 可以使用對(duì)象解構(gòu)來(lái)創(chuàng)建對(duì)作用域插槽數(shù)據(jù)的直接引用,而不是使用單個(gè)變量名。換句話(huà)說(shuō),可以使用 v-slot="{user}" 代替 v-slot="slotProps" ,然后可以直接使用 user 而不是 slotProps.user 。
  • 所以,上面的例子可以這樣重寫(xiě)

    // app.vue
    <template>
     <current-user v-slot="{user}">
     {{ user.firstName }}
     </current-user>
    </template>

    還有幾點(diǎn)要記?。?/p>

  • 可以使用 v-bind 指令綁定多個(gè)值。
  • 也可以將函數(shù)傳遞到作用域槽。許多庫(kù)使用它來(lái)提供可重用的函數(shù)組件。
  • v-slot 的別名是 # 。因此,可以用 #header="data" 來(lái)代替 v-slot:header="data" 。還可以使用 #header 來(lái)代替 v-slot:header (前提:不是作用域插槽時(shí))。對(duì)于默認(rèn)插槽,在使用別名時(shí)需要 指定默認(rèn)名稱(chēng) 。換句話(huà)說(shuō),需要這樣寫(xiě) #default="data" 而不是 #="data" 。
  • 可以從 文檔 中了解更多的細(xì)節(jié),但這足以幫助你理解在本文剩下部分中討論的內(nèi)容。

    你能用插槽做什么?

    插槽不是為了一個(gè)目的而構(gòu)建的,或者至少如果它們是,它們已經(jīng)超越了最初的意圖,成為做許多不同事物的強(qiáng)大工具。

    可重用的模式

    組件總是被設(shè)計(jì)為可重用的,但是某些模式對(duì)于使用單個(gè)“普通”組件來(lái)實(shí)施是不切實(shí)際的,因?yàn)闉榱俗远x它,需要的 props 數(shù)量可能過(guò)多或者需要通過(guò) props 傳遞大部分內(nèi)容或其它組件。

    插槽可用包裹外部的HTML標(biāo)簽或者組件,并允許其他HTML或組件放在具名插槽對(duì)應(yīng)名稱(chēng)的插槽上。

    對(duì)于的第一個(gè)例子,從簡(jiǎn)單的東西開(kāi)始:一個(gè)按鈕。假設(shè)咱們的團(tuán)隊(duì)正在使用 Bootstrap。使用Bootstrap,按鈕通常與基本的 “btn” 類(lèi)和指定顏色的類(lèi)綁定在一起,比如 “btn-primary” 。你還可以添加 size 類(lèi),比如 'btn-lg' 。

    為了簡(jiǎn)單起見(jiàn),現(xiàn)在讓我們假設(shè)你的應(yīng)用使用 btn 、 btn-primary 和 btn-lg 。你不希望總是必須在按鈕上寫(xiě)下這三個(gè)類(lèi),或者你不相信新手會(huì)記得寫(xiě)下這三個(gè)類(lèi)。

    在這種情況下,可以創(chuàng)建一個(gè)自動(dòng)包含所有這三個(gè)類(lèi)的組件,但是如何允許自定義內(nèi)容? prop 不實(shí)用,因?yàn)樵试S按鈕包含各種HTML,因此我們應(yīng)該使用一個(gè)插槽。

    <!-- my-button.vue -->
    <template>
     <button class="btn btn-primary btn-lg">
     <slot>Click Me!</slot>
     </button>
    </template>

    現(xiàn)在我們可以在任何地方使用它,無(wú)論你想要什么內(nèi)容

    <!-- 使用 my-button.vue -->
    <template>
     <my-button>
     <img src="https://www.gxlcms.com/img/awesome-icon.jpg"> 我是小智!
     </my-button>
    </template>

    當(dāng)然,你可以選擇比按鈕更大的東西。 堅(jiān)持使用Bootstrap,讓我們看一個(gè)模態(tài):

    <!-- my-modal.vue -->
    <template>
    <div class="modal" tabindex="-1" role="dialog">
     <div class="modal-dialog" role="document">
     <div class="modal-content">
     <div class="modal-header">
     <slot name="header"></slot>
     <button type="button" class="close" data-dismiss="modal" aria-label="Close">
     <span aria-hidden="true">×</span>
     </button>
     </div>
     <div class="modal-body">
     <slot name="body"></slot>
     </div>
     <div class="modal-footer">
     <slot name="footer"></slot>
     </div>
     </div>
     </div>
    </div>
    </template>

    現(xiàn)在,使用它:

    <!-- 使用 my-modal.vue -->
    <template>
     <my-modal>
     <template #header>
     <h5>大家最棒!</h5>
     </template>
     <template #body>
     <p>大家加油</p>
     </template>
     <template #footer>
     <em>大家好樣的!</em>
     </template>
     </my-modal>
    </template>

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

    復(fù)用函數(shù)

    Vue組件并不完全是關(guān)于HTML和CSS的。它們是用JavaScript構(gòu)建的,所以也是關(guān)于函數(shù)的。插槽對(duì)于一次性創(chuàng)建函數(shù)并在多個(gè)地方使用功能非常有用。讓我們回到模態(tài)示例并添加一個(gè)關(guān)閉模態(tài)的函數(shù)

    <!-- my-modal.vue -->
    <template>
    <div class="modal" tabindex="-1" role="dialog">
     <div class="modal-dialog" role="document">
     <div class="modal-content">
     <div class="modal-header">
     <slot name="header"></slot>
     <button type="button" class="close" data-dismiss="modal" aria-label="Close">
     <span aria-hidden="true">×</span>
     </button>
     </div>
     <div class="modal-body">
     <slot name="body"></slot>
     </div>
     <div class="modal-footer"> 
     <slot name="footer" :closeModal="closeModal"></slot>
     </div>
     </div>
     </div>
    </div>
    </template>
    
    <script>
    export default {
     //...
     methods: {
     closeModal () {
     // 關(guān)閉對(duì)話(huà)框時(shí),需要做的事情
     }
     }
    }
    </script>

    當(dāng)使用此組件時(shí),可以向 footer 添加一個(gè)可以關(guān)閉模​​態(tài)的按鈕。 通常,在Bootstrap模式的情況下,可以將 data-dismiss =“modal” 添加到按鈕來(lái)進(jìn)行關(guān)閉。

    但我們希望隱藏Bootstrap 特定的東西。 所以我們傳遞給他們一個(gè)他們可以調(diào)用的函數(shù),這樣使用者就不會(huì)知道我們有使用 Bootstrap 的東西。

    <!-- 使用 my-modal.vue -->
    <template>
     <my-modal>
     <template #header>
     <h5>Awesome Interruption!</h5>
     </template>
     <template #body>
     <p>大家加油!</p>
     </template>
     <template #footer="{closeModal}">
     <button @click="closeModal">
     點(diǎn)我可以關(guān)閉煩人的對(duì)話(huà)框
     </button>
     </template>
     </my-modal>
    </template>

    無(wú)渲染組件

    最后,可以利用你所知道的關(guān)于使用插槽來(lái)傳遞可重用函數(shù)的知識(shí),并剝離所有HTML,只使用插槽。這就是無(wú)渲染組件的本質(zhì):一個(gè)只提供函數(shù)而不包含任何HTML的組件。

    使組件真正無(wú)渲染可能有點(diǎn)棘手,因?yàn)樾枰帉?xiě) render 函數(shù)而不是使用模板來(lái)消除對(duì)根元素的依賴(lài),但它可能并不總是必要的。 來(lái)看看一個(gè)先使用模板的簡(jiǎn)單示例:

    <template>
     <transition name="fade" v-bind="$attrs" v-on="$listeners">
     <slot></slot>
     </transition>
    </template>
    <style>
    .fade-enter-active,
    .fade-leave-active {
     transition: opacity 0.3s;
    }
    .fade-enter, .fade-leave-to {
     opacity: 0;
    }
    </style>

    這是一個(gè)無(wú)渲染組件的奇怪例子,因?yàn)樗踔翛](méi)有任何JavaScript。這主要是因?yàn)槲覀冋趧?chuàng)建一個(gè)內(nèi)置無(wú)渲染函數(shù)的預(yù)配置可重用版本: transition 。

    是的,Vue有內(nèi)置的無(wú)渲染組件。這個(gè)特殊的例子取自Cristi Jora的一篇關(guān)于 可重用transition 的文章,展示了一種創(chuàng)建無(wú)渲染組件的簡(jiǎn)單方法,該組件可以標(biāo)準(zhǔn)化整個(gè)應(yīng)用程序中使用的 transition 。

    對(duì)于我們的另一個(gè)示例,我們將創(chuàng)建一個(gè)組件來(lái)處理切換 Promise 的不同狀態(tài)中顯示的內(nèi)容: pending、resolved 和 failed。這是一種常見(jiàn)的模式,雖然它不需要很多代碼,但是如果沒(méi)有為了可重用性而提取邏輯,它會(huì)使很多組件變得混亂。

    <!-- promised.vue -->
    <template>
     <span>
     <slot name="rejected" v-if="error" :error="error"></slot>
     <slot name="resolved" v-else-if="resolved" :data="data"></slot>
     <slot name="pending" v-else></slot>
     </span>
    </template>
    <script>
    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
     }
     }
    }
    </script>

    這是怎么回事,小老弟?首先,請(qǐng)注意,該組件接收一個(gè)Promise 類(lèi)型參數(shù)。在 watch 部分中,監(jiān)聽(tīng) promise 的變化,當(dāng) promise 發(fā)生變化時(shí),清除狀態(tài),然后調(diào)用 then 并 catch promise,當(dāng) promise 成功完成或失敗時(shí)更新?tīng)顟B(tài)。

    然后,在模板中,我們根據(jù)狀態(tài)顯示一個(gè)不同的槽。請(qǐng)注意,我們沒(méi)有保持它真正的無(wú)渲染,因?yàn)槲覀冃枰粋€(gè)根元素來(lái)使用模板。我們還將 data 和 error 傳遞到相關(guān)的插槽范圍。

    <template>
     <div>
     <promised :promise="somePromise">
     <template #resolved="{ data }">
     Resolved: {{ data }}
     </template>
     <template #rejected="{ error }">
     Rejected: {{ error }}
     </template>
     <template #pending>
     請(qǐng)求中...
     </template>
     </promised>
     </div>
    </template>
    ...

    我們將 somePromise 傳遞給無(wú)渲染組件。 然后等待它完成,對(duì)于 pending 的插槽,顯示“請(qǐng)求中...”。 如果成功,顯示“Resolved:對(duì)應(yīng)的值”。 如果失敗,顯示“已Rejected:失敗的原因”。 現(xiàn)在我們不再需要跟蹤此組件中的 promise 的狀態(tài),因?yàn)樵摬糠直焕龅剿约旱目芍赜媒M件中。

    那么,我們可以做些什么來(lái)繞過(guò) promised.vue 中的插槽? 要?jiǎng)h除它,我們需要?jiǎng)h除 template 部分并向我們的組件添加 render 函數(shù):

    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']()
    }

    這里沒(méi)有什么太復(fù)雜的。我們只是使用一些 if 塊來(lái)查找狀態(tài),然后返回正確的作用域 slot (通過(guò) this.$ scopedslot ['SLOTNAME'](…) ),并將相關(guān)數(shù)據(jù)傳遞到 slot 作用域。當(dāng)你不使用模板時(shí),可以跳過(guò)使用 .vue 文件擴(kuò)展名,方法是將JavaScript從 script 標(biāo)記中提取出來(lái),然后將其放入 .js 文件中。在編譯這些Vue文件時(shí),這應(yīng)該會(huì)給你帶來(lái)非常小的性能提升。

    總結(jié)

    Vue的插槽將基于組件的開(kāi)發(fā)提升到了一個(gè)全新的水平,雖然本文已經(jīng)展示了許多可以使用插槽的好方法,但還有更多的插槽。

    以上所述是小編給大家介紹的vue 2.6 中 slot 的新用法,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
    如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!

    聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    詳解vue 2.6 中 slot 的新用法

    詳解vue 2.6 中 slot 的新用法:最近發(fā)布不久的Vue 2.6,使用插槽的語(yǔ)法變得更加簡(jiǎn)潔。 對(duì)插槽的這種改變讓我對(duì)發(fā)現(xiàn)插槽的潛在功能感興趣,以便為我們基于Vue的項(xiàng)目提供可重用性,新功能和更清晰的可讀性。 真正有能力的插槽是什么? 如果你是Vue的新手,或者還沒(méi)有看到2.6版的變化,請(qǐng)繼續(xù)
    推薦度:
    標(biāo)簽: VUE 用法 詳解
    • 熱門(mén)焦點(diǎn)

    最新推薦

    猜你喜歡

    熱門(mén)推薦

    專(zhuān)題
    Top