搜尋
首頁web前端Vue.js深入理解Vue中的插槽、內容分發、具名插槽

這篇文章跟大家分享Vue進階技巧,深入理解下Vue中的插槽、內容分發、具名插槽,希望對大家有幫助。

深入理解Vue中的插槽、內容分發、具名插槽

插槽Slots簡介

#Vue中元件的資料可以透過props傳遞,或透過事件的方式進行獲取傳遞,但當需要接收模板內容(任意合法的模板內容,程式碼片段、Vue元件)時,就需要使用插槽來實現了。當然也可以透過函數式程式設計間接實現;【相關推薦:vuejs影片教學

深入理解Vue中的插槽、內容分發、具名插槽

  • 可以將插槽理解為js中的函數進行編譯
// 父元素传入插槽内容
FancyButton('Click me!')

// FancyButton 在自己的模板中渲染插槽内容
function FancyButton(slotContent) {
    return `<button>
      ${slotContent}
    </button>`
}
  • 最好的封裝方式是將共性抽取到元件中,將不同點暴露為插槽- 抽取共性,保留不同
  • 父元件模板的所有東西都會在父元件作用域中編譯,子元件模板的所有東西都會在子元件作用域內編譯- 編譯作用域

slot-scope析

常規的slot可以用於自訂元件的模板,但只是限制於固定的模板,無法自訂內部的具體的某一項,即常規的slot無法實現對組件循環體的每一項進行不同的內容分發,此時可以透過slot-scope進行實現,本質上和slot一樣,不同點在於可以進行參數傳遞

//普通的组件定义
        
  •     {{ book.name }}     
//slot-scope组件定义
        
  •                                   {{ book.name }}              
//父组件使用     

使用slot-scope時,當父元件使用該API,對應的插槽會取代模板中的slot進行展示

常用API淺析

具名插槽

在元件中定義多個插槽出口可以相容多個不同需求的相容性,使得多個插槽內容傳入到各自的插槽出口中;當插槽中配置了name屬性時,此插槽就稱為具名插槽(named slots),沒有提供name的插槽會隱含命名為「default」

深入理解Vue中的插槽、內容分發、具名插槽

  • v-slot 可以簡寫為##,其值對應於插槽中的 name對應的值;
  • 當在一個元件中同時存在預設插槽和具名插槽時,所有位於頂層的非template節點都被隱式的視為預設插槽的內容,因此可以省略預設插槽的template節點標籤;
<com>
    <!-- 隐式的默认插槽 -->
    <!-- <p>A paragraph for the main content.</p>
    <p>And another one.</p> -->
    <template>
        <p>A paragraph for the main content.</p>
        <p>And another one.</p>
    </template>
    <template>
        <p>Here's some contact info</p>
    </template>
</com>
##作用域插槽
普通的插槽,是無法取得其他作用域下的資料的,即

父元件範本中的表達式只能存取父元件的作用域;子元件範本中的表達式只能存取子元件元件的作用域但在某些情況下,插槽中的內容想要同時使用父元件和子元件內的數據,可以透過像元件傳遞資料
props那樣,讓子元件在渲染時將一​​部分資料提供給插槽,這樣在元件外部(父元件)中就可以使用子元件中的資料了-透過slot的方式

#子元件傳入插槽的props 作為了 v-slot 指令的值,可以在插槽內的表達式中訪問,其中name是Vue刻意保留的attribute,不會作為props進行傳遞

    資料傳遞
//子组件
<template> 
    <slot></slot> 
</template>
    #資料接收
    • 預設插槽接收
    //父组件 - 使用方
    <mycom>
      {{ shopInfo }} {{ userInfo }}
    </mycom>
    具名插槽接收
<mycom>
  <template>
    {{ shopInfo }}
  </template>

  <template>
    {{ introduction }}
  </template>

  <template>
    {{ userInfo }}
  </template>
</mycom>
使用slot-scope時,用最後一個slot-scope取代模板中的slot
  • <cpm>
        <!-- 不显示 -->
        <div>555</div>
        <!-- 不显示 -->
        <div>
            <div>{{scope.name}}</div>
        </div>
        <!-- 显示 -->
        <div>
            <div>{{scope}}</div>
            <div>{{scope.name}}</div>
            <div>{{scope.age}}</div>
        </div>
    </cpm>
      #使用作用域插槽時,可以實現既可以重複使用子元件slot,又可以使得slot的內容不一致,它允許使用者傳遞一個模板而不是已經渲染好的元素給插槽,所謂作用域是指模板雖然在父級作用域中渲染的,但是卻可以拿到子組件的資料
    • 常規的v-bind需要攜帶參數key值進行傳遞,例如
    • v-bind:info = '123 ';但有時會省略這個key值,直接進行傳遞數據,如v-bind = 'item',這種用法會將整個物件的所有屬性都綁定到當前元素上,適用於需要綁定的屬性過多的場景
    // data: {
    //     shapes: [
    //         { name: 'Square', sides: 4 },
    //         { name: 'Hexagon', sides: 6 },
    //         { name: 'Triangle', sides: 3 }
    //     ],
    //     colors: [
    //         { name: 'Yellow', hex: '#F4D03F', },
    //         { name: 'Green', hex: '#229954' },
    //         { name: 'Purple', hex: '#9B59B6' }
    //     ]
    // }
    <my-list>
        <template>
            <div>{{ shape.name }} <small>({{ shape.sides }} sides)</small>
    </div>
        </template>
    </my-list>
    <my-list>
        <template>
            <div>
                <div></div>
                {{ color.name }}
            </div>
        </template>
    </my-list>
    <div>
        <div>{{ title }}</div>
        <div>
            <div>
                <slot></slot>
            </div>
        </div>
    </div>
    
    
    Vue.component('my-list', {
        template: '#my-list',
        props: [ 'title', 'items' ]
    });
    遞歸元件
    遞歸元件就是指元件在模板中呼叫自己,由於是組件自身調用,就不能像常規組件定義一樣,可以省略組件的name配置,組件的遞歸需要依賴於自身的name配置(name還用於遍歷組件的name選項來查找組件的實例);

    • 满足条件
      • 需要给组件设置一个name属性
      • 需要有一个明确的结束条件
    <template>
        <div>
            <my-component></my-component>
        </div>
    </template>
    <script>
    export default {
        name:&#39;my-component&#39;,
        props: {
            count: {
                type: Number,
                default: 1
            }
        }
    }
    </script>
    动态组件

    有时候我们需要根据一些条件,动态的切换/选择某个组件,在函数式组件中,没有上下文的概念,常用于程序化的在多个组件中选择一个,可以间接的解决动态切换组件的需求,缺点是基于js对象进行开发,不方便开发;
    Vue官方提供了一个内置组件<component></component>和is的属性,用来解决上述的问题

    <component></component>
    //component 就是js import进的组件实例,其值可以是标签名、组件名、直接绑定一个对象等
    • 为了使得组件具有缓存作用,可以使用的内置组件,这样只要不离开当前页面,切换到其他组件后deforeDestory不会执行,因此组件具有了缓存功能

    拓展

    components的第二种写法

    常规的组件components是直接通过引用定义好的组件进行展示的,也可以直接在当前组件内定义,然后通过配置components进行渲染

    <div>
        <cpn></cpn>
    </div>
    <template>
        <div>
            <h2 id="Lbxin">Lbxin</h2>
            <p>class - 11</p>
        </div>
    </template>
    <script>
    var app = new Vue({
        el: &#39;#app&#39;,
        data: {
            isShow: true
        },
        components: {
            cpn: {
                template: &#39;#com&#39;,
                data() {
                    isShow: false
                }
            }
        }
    })
    </script>

    Web Component <slot></slot> 简介

    HTML的slot元素,是Web Components技术套件的一部分,是Web组件内的一个占位符,该占位符可以在后期使用自己的标记语言进行填充,这样可以创建单独的DOM树,并将其与其他的组件组合在一起 -- MDN

    常见的填充Web组件的shadow DOM的模板有template和slot

    • 模板 - Templates

      • 需要在网页上重复的使用相同的标记结构时,为了避免CV的操作可以通过模板的方式进行实现
      • 需要注意的是模板 - Template 和其内部的内容是不会在DOM中呈现的,可以通过js进行访问并添加到DOM中,从而在界面上进行展示
      <template>
        <p>My paragraph</p>
      </template>
      let template = document.getElementById('my-paragraph');
      let templateContent = template.content;
      document.body.appendChild(templateContent);
      • 可以配合Web Component一起使用,实现纯js自定义的组件
      customElements.define('my-paragraph',
        class extends HTMLElement {
          constructor() {
            super();
            let template = document.getElementById('my-paragraph');
            let templateContent = template.content;
      
            const shadowRoot = this.attachShadow({mode: 'open'})
              .appendChild(templateContent.cloneNode(true));
        }
      })
      
      // 自定义标签使用
      <my-paragraph></my-paragraph>
      • 后续的样式逻辑也需要加在template中,方便通过后续的相关逻辑(如template.content获取到然后打入到指定的容器中)
    • Web Component简介

      • Web Component的一个很重要的属性就是封装 - 可以将标记结构、样式和行为影藏起来,并于界面上的其他代码隔离开来,保证代码的独立性

      • Web Component标准非常重要的一个特性是,使得开发者可以将HTML页面的功能封住成custom elements(自定义标签)

      • customElements 接口用来实现一个对象,允许开发者注册一个custom elements的信息,返回已注册的自定义标签的信息;

      • customElements.define方法用来注册一个custom element,接收三个参数

        • 参数一:表明创建元素的名称,其注册的名称不能简单的单词,需要由短划线进行拼接

        • 参数二:用于定义元素行为的类

        • 参数三:一个包含extends属性配置的配置对象,可选,指定了所创建的自定义元素是继承于哪个内置的元素,可以继承任何内置的元素;

          customElements.define(
              'word-count', 
              WordCount, 
              { extends: 'p' }
          );

          可以使用ES2015的类实现

          class WordCount extends HTMLParagraphElement {
            constructor() {
              // 必须首先调用 super 方法
              super();
              // 元素的功能代码写在这里
              ...
            }
          }
      • 自定义标签的类型

        • 类型一:Autonomous custom elements 是独立的元素,它不继承其他内建的 HTML 元素,可以直接通过标签的方式进行HTML使用<popup-info></popup-info>,也可以通过js的方式进行使用document.createElement("popup-info")
        • 类型二:Customized built-in elements 继承自基本的 HTML 元素。在创建时,你必须指定所需扩展的元素,使用时,需要先写出基本的元素标签,并通过 is属性指定 custom element 的名称;<p is="word-count"></p>document.createElement("p", { is: "word-count" })

        参考文献 - MDN

    • shadow DOM简介

      • 图解Shandow DOM

      深入理解Vue中的插槽、內容分發、具名插槽

      • Shadow host:一个常规 DOM 节点,Shadow DOM 会被附加到这个节点上。

      • Shadow tree:Shadow DOM 内部的 DOM 树。

      • Shadow boundary:Shadow DOM 结束的地方,也是常规 DOM 开始的地方。

      • Shadow root: Shadow tree 的根节点。

      shadow DOM主要是将一个隐藏的、独立的DOM树附加到常规的DOM树上,是以shadow DOM节点为起始根节点,在这个根节点的下方,可以是任意的元素,和普通的DOM元素一致

    如常见的video标签,其内部的一些控制器和按钮等都是通过Shandow DOM进行维护的,开发者可以通过这个API进行自己独立的逻辑控制

    • 基本用法

      • Element.attachShadow()方法可以将一个shadow DOM添加到任何一个元素上,接收一个配置对象参数,该对象有一个mode的属性,值可以是open - 可以通过外部js获取 Shadow DOM和closed - 外部不可以通过js进行获取 Shadow DOM
      let shadow1 = elementRef.attachShadow({mode: 'open'});
      let shadow2 = elementRef.attachShadow({mode: 'closed'});
      let myShadowDom = shadow1.shadowRoot; // 具体内容
      let myShadowDom = shadow2.shadowRoot; //null
      • 当需要将一个shadow DOM添加到自定义的标签上时,可以在自定义的构造函数中添加如下逻辑;
      let shadow = this.attachShadow({mode: 'open'});
      // 将一个shadow DOM添加到一个元素上之后就可以使用DOM API进行操作访问了

    (学习视频分享:web前端开发编程基础视频

    以上是深入理解Vue中的插槽、內容分發、具名插槽的詳細內容。更多資訊請關注PHP中文網其他相關文章!

  • 陳述
    本文轉載於:掘金社区。如有侵權,請聯絡admin@php.cn刪除
    vue.js的功能:增強前端的用戶體驗vue.js的功能:增強前端的用戶體驗Apr 19, 2025 am 12:13 AM

    Vue.js通過多種功能提升用戶體驗:1.響應式系統實現數據即時反饋;2.組件化開發提高代碼復用性;3.VueRouter提供平滑導航;4.動態數據綁定和過渡動畫增強交互效果;5.錯誤處理機制確保用戶反饋;6.性能優化和最佳實踐提升應用性能。

    vue.js:定義其在網絡開發中的作用vue.js:定義其在網絡開發中的作用Apr 18, 2025 am 12:07 AM

    Vue.js在Web開發中的角色是作為一個漸進式JavaScript框架,簡化開發過程並提高效率。 1)它通過響應式數據綁定和組件化開發,使開發者能專注於業務邏輯。 2)Vue.js的工作原理依賴於響應式系統和虛擬DOM,優化性能。 3)實際項目中,使用Vuex管理全局狀態和優化數據響應性是常見實踐。

    了解vue.js:主要是前端框架了解vue.js:主要是前端框架Apr 17, 2025 am 12:20 AM

    Vue.js是由尤雨溪在2014年發布的漸進式JavaScript框架,用於構建用戶界面。它的核心優勢包括:1.響應式數據綁定,數據變化自動更新視圖;2.組件化開發,UI可拆分為獨立、可複用的組件。

    Netflix的前端:React(或VUE)的示例和應用Netflix的前端:React(或VUE)的示例和應用Apr 16, 2025 am 12:08 AM

    Netflix使用React作為其前端框架。 1)React的組件化開發模式和強大生態系統是Netflix選擇它的主要原因。 2)通過組件化,Netflix將復雜界面拆分成可管理的小塊,如視頻播放器、推薦列表和用戶評論。 3)React的虛擬DOM和組件生命週期優化了渲染效率和用戶交互管理。

    前端景觀:Netflix如何處理其選擇前端景觀:Netflix如何處理其選擇Apr 15, 2025 am 12:13 AM

    Netflix在前端技術上的選擇主要集中在性能優化、可擴展性和用戶體驗三個方面。 1.性能優化:Netflix選擇React作為主要框架,並開發了SpeedCurve和Boomerang等工具來監控和優化用戶體驗。 2.可擴展性:他們採用微前端架構,將應用拆分為獨立模塊,提高開發效率和系統擴展性。 3.用戶體驗:Netflix使用Material-UI組件庫,通過A/B測試和用戶反饋不斷優化界面,確保一致性和美觀性。

    React與Vue:Netflix使用哪個框架?React與Vue:Netflix使用哪個框架?Apr 14, 2025 am 12:19 AM

    NetflixusesAcustomFrameworkcalled“ Gibbon” BuiltonReact,notReactorVuedIrectly.1)TeamSperience:selectBasedonFamiliarity.2)ProjectComplexity:vueforsimplerprojects:reactforforforproproject,reactforforforcompleplexones.3)cocatizationneedneeds:reactoffipicatizationneedneedneedneedneedneeds:reactoffersizationneedneedneedneedneeds:reactoffersizatization needefersmoreflexibleise.4)

    框架的選擇:是什麼推動了Netflix的決定?框架的選擇:是什麼推動了Netflix的決定?Apr 13, 2025 am 12:05 AM

    Netflix在框架選擇上主要考慮性能、可擴展性、開發效率、生態系統、技術債務和維護成本。 1.性能與可擴展性:選擇Java和SpringBoot以高效處理海量數據和高並發請求。 2.開發效率與生態系統:使用React提升前端開發效率,利用其豐富的生態系統。 3.技術債務與維護成本:選擇Node.js構建微服務,降低維護成本和技術債務。

    反應,vue和Netflix前端的未來反應,vue和Netflix前端的未來Apr 12, 2025 am 12:12 AM

    Netflix主要使用React作為前端框架,輔以Vue用於特定功能。 1)React的組件化和虛擬DOM提升了Netflix應用的性能和開發效率。 2)Vue在Netflix的內部工具和小型項目中應用,其靈活性和易用性是關鍵。

    See all articles

    熱AI工具

    Undresser.AI Undress

    Undresser.AI Undress

    人工智慧驅動的應用程序,用於創建逼真的裸體照片

    AI Clothes Remover

    AI Clothes Remover

    用於從照片中去除衣服的線上人工智慧工具。

    Undress AI Tool

    Undress AI Tool

    免費脫衣圖片

    Clothoff.io

    Clothoff.io

    AI脫衣器

    AI Hentai Generator

    AI Hentai Generator

    免費產生 AI 無盡。

    熱工具

    mPDF

    mPDF

    mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

    SublimeText3 英文版

    SublimeText3 英文版

    推薦:為Win版本,支援程式碼提示!

    SublimeText3漢化版

    SublimeText3漢化版

    中文版,非常好用

    Dreamweaver Mac版

    Dreamweaver Mac版

    視覺化網頁開發工具

    VSCode Windows 64位元 下載

    VSCode Windows 64位元 下載

    微軟推出的免費、功能強大的一款IDE編輯器