麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > JavaScript > 正文

詳解vue 2.6 中 slot 的新用法

2019-11-19 11:12:46
字體:
供稿:網(wǎng)友

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

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

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

插槽是什么?

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

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

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

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

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

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

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

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

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

多個/命名的插槽

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

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

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

// 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)容添加到默認槽中,只需將其直接放在 titled-frame 組件中。但是,要將內(nèi)容添加到命名槽中,我們需要用 v-slot 指令將代碼包裹在在 template 標記中。在 v-slot 之后添加冒號 (:) ,然后寫出要傳遞內(nèi)容的 slot 的名稱。

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

作用域插槽

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

// current-user.vue<template> <span> <slot v-bind:user="user"> {{ user.lastName }} </slot> </span></template><script>export default { data () { return { user: ... } }}</script>

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

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

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

這里有幾點需要注意:

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

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

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

還有幾點要記?。?/strong>

  • 可以使用 v-bind 指令綁定多個值。
  • 也可以將函數(shù)傳遞到作用域槽。許多庫使用它來提供可重用的函數(shù)組件。
  • v-slot 的別名是 # 。因此,可以用 #header="data" 來代替 v-slot:header="data" 。還可以使用 #header 來代替 v-slot:header (前提:不是作用域插槽時)。對于默認插槽,在使用別名時需要 指定默認名稱 。換句話說,需要這樣寫 #default="data" 而不是 #="data" 。

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

你能用插槽做什么?

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

可重用的模式

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

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

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

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

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

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

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

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

當然,你可以選擇比按鈕更大的東西。 堅持使用Bootstrap,讓我們看一個模態(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>

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

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

Vue組件并不完全是關(guān)于HTML和CSS的。它們是用JavaScript構(gòu)建的,所以也是關(guān)于函數(shù)的。插槽對于一次性創(chuàng)建函數(shù)并在多個地方使用功能非常有用。讓我們回到模態(tài)示例并添加一個關(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)閉對話框時,需要做的事情 } }}</script>

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

但我們希望隱藏Bootstrap 特定的東西。 所以我們傳遞給他們一個他們可以調(diào)用的函數(shù),這樣使用者就不會知道我們有使用 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"> 點我可以關(guān)閉煩人的對話框 </button> </template> </my-modal></template>

無渲染組件

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

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

<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>

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

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

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

<!-- 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>

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

然后,在模板中,我們根據(jù)狀態(tài)顯示一個不同的槽。請注意,我們沒有保持它真正的無渲染,因為我們需要一個根元素來使用模板。我們還將 data 和 error 傳遞到相關(guān)的插槽范圍。

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

我們將 somePromise 傳遞給無渲染組件。 然后等待它完成,對于 pending 的插槽,顯示“請求中...”。 如果成功,顯示“Resolved:對應(yīng)的值”。 如果失敗,顯示“已Rejected:失敗的原因”。 現(xiàn)在我們不再需要跟蹤此組件中的 promise 的狀態(tài),因為該部分被拉出到它自己的可重用組件中。

那么,我們可以做些什么來繞過 promised.vue 中的插槽? 要刪除它,我們需要刪除 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']()}

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

總結(jié)

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

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

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 国产一区二区久久精品 | 一级电影免费在线观看 | 久草视频福利在线观看 | 国产乱xxxx | 亚洲自拍第二页 | 国产高潮好爽好大受不了了 | 久久国产精品二国产精品中国洋人 | 一级美女大片 | 免费在线成人网 | 精品一区二区6 | 精品在线观看一区 | 日日夜av | 免费a级黄色毛片 | 亚洲精品午夜国产va久久成人 | 天天曰夜夜操 | 国产午夜精品一区二区三区视频 | 播色网 | 成人免费福利视频 | 牛牛a级毛片在线播放 | 亚洲综合视频一区 | 国产高潮失禁喷水爽到抽搐视频 | 久久99国产精品久久99果冻传媒 | 亚洲一区二区三区视频免费 | 国产精品久久久麻豆 | 一级做a爱片久久 | 少妇一级淫片免费放播放 | 欧美一级黄色片在线观看 | 亚洲九九爱 | 色综合久久久久久久久久久 | 欧美在线观看黄色 | 国产一级一区 | 久久综合精品视频 | 97久色| 特级a欧美做爰片毛片 | 奇米888一区二区三区 | 大学生一级毛片在线视频 | av在线免费看片 | 一区国产在线 | 欧美日韩国产成人在线观看 | 国产亚洲精品视频中文字幕 | 蜜桃av鲁一鲁一鲁一鲁 |