91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Vue中的插槽、內容分發、具名插槽應用實例分析

發布時間:2022-10-13 09:11:14 來源:億速云 閱讀:136 作者:iii 欄目:編程語言

今天小編給大家分享一下Vue中的插槽、內容分發、具名插槽應用實例分析的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

插槽 Slots簡介

Vue中組件的數據可以通過props進行傳遞,或者通過事件的方式進行獲取傳遞,但當需要接收模板內容(任意合法的模板內容,代碼片段、Vue組件)時,就需要使用插槽來實現了。當然也可以通過函數式編程間接實現。

Vue中的插槽、內容分發、具名插槽應用實例分析

  • 可以將插槽理解為js中的函數進行編譯

// 父元素傳入插槽內容
FancyButton('Click me!')

// FancyButton 在自己的模板中渲染插槽內容
function FancyButton(slotContent) {
    return `<button class="fancy-btn">
      ${slotContent}
    </button>`
}

  • 最好的封裝方式是將共性抽取到組件中,將不同點暴露為插槽 - 抽取共性,保留不同

  • 父組件模板的所有東西都會在父組件作用域中編譯,子組件模板的所有東西都會在子組件作用域內編譯 - 編譯作用域

slot-scope淺析

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

//普通的組件定義
<ul>
    <li v-for="book in books" :key="book.id">
    {{ book.name }}
    </li>
</ul>


//slot-scope組件定義
<ul>
    <li v-for="book in books" :key="book.id">
        <slot :book="book" name="bookInfo">
            <!-- 默認內容 -->
            {{ book.name }}
        </slot>
    </li>
</ul>

//父組件使用
<book-list :books="books">
    <template slot-scope="slotProps" slot="bookInfo">
        <span v-if="slotProps.book.sale">限時優惠</span>
        {{ slotProps.book.name }}
    </template>
</book-list>

使用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 #default>
        <p>A paragraph for the main content.</p>
        <p>And another one.</p>
    </template>
    <template #footer>
        <p>Here's some contact info</p>
    </template>
</Com>

作用域插槽

普通的插槽,是無法獲取其他作用域下的數據的,即父組件模板中的表達式只能訪問父組件的作用域;子組件模板中的表達式只能訪問子組件的作用域
但在某些情況下,插槽中的內容想要同時使用父組件和子組件內的數據,可以通過像組件傳遞數據props那樣,讓子組件在渲染時將一部分數據提供給插槽,這樣在組件外部(父組件)中就可以使用子組件中的數據了-通過slot的方式

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

  • 數據傳遞

//子組件
<template> 
    <slot :shopInfo="shopInfo" :userInfo="userInfo"></slot> 
</template>

  • 數據接收

    //父組件 - 使用方
    <MyCom v-slot="{shopInfo,userInfo}">
     {{ shopInfo }} {{ userInfo }}
    </MyCom>
  • <MyCom>
      <template v-slot:header="shopInfo">
        {{ shopInfo }}
      </template>

      <template #default="introduction">
        {{ introduction }}
      </template>

      <template #footer="userInfo">
        {{ userInfo }}
      </template>
    </MyCom>
    • 具名插槽接收

    • 默認插槽接收

  • 使用slot-scope時,用最后一個slot-scope替換模板中的slot

<cpm>
    <!-- 不顯示 -->
    <div>555</div>
    <!-- 不顯示 -->
    <div slot-scope="scope">
        <div>{{scope.name}}</div>
    </div>
    <!-- 顯示 -->
    <div slot-scope="scope">
        <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 title="Shapes" :items="shapes">
    <template scope="shape">
        <div>{{ shape.name }} <small>({{ shape.sides }} sides)</small></div>
    </template>
</my-list>
<my-list title="Colors" :items="colors">
    <template scope="color">
        <div>
            <div class="swatch" :style="{ background: color.hex }"></div>
            {{ color.name }}
        </div>
    </template>
</my-list>
<div id="my-list">
    <div class="title">{{ title }}</div>
    <div class="list">
        <div v-for="scope in items">
            <slot v-bind="scope"></slot>
        </div>
    </div>
</div>


Vue.component('my-list', {
    template: '#my-list',
    props: [ 'title', 'items' ]
});

遞歸組件

遞歸組件就是指組件在模板中調用自己,由于是組件自身調用,就不能像常規組件定義一樣,可以省略組件的name配置,組件的遞歸需要依賴于自身的name配置(name還用于遍歷組件的name選項來查找組件的實例);

  • 滿足條件

    • 需要給組件設置一個name屬性

    • 需要有一個明確的結束條件

<template>
    <div>
        <my-component :count="count + 1" v-if="count
        <= 5"></my-component>
    </div>
</template>
<script>
export default {
    name:'my-component',
    props: {
        count: {
            type: Number,
            default: 1
        }
    }
}
</script>

動態組件

有時候我們需要根據一些條件,動態的切換/選擇某個組件,在函數式組件中,沒有上下文的概念,常用于程序化的在多個組件中選擇一個,可以間接的解決動態切換組件的需求,缺點是基于js對象進行開發,不方便開發;
Vue官方提供了一個內置組件<component>和is的屬性,用來解決上述的問題

<component :is="component"></component>
//component 就是js import進的組件實例,其值可以是標簽名、組件名、直接綁定一個對象等

為了使得組件具有緩存作用,可以使用的內置組件,這樣只要不離開當前頁面,切換到其他組件后deforeDestory不會執行,因此組件具有了緩存功能

拓展

components的第二種寫法

常規的組件components是直接通過引用定義好的組件進行展示的,也可以直接在當前組件內定義,然后通過配置components進行渲染

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

Web Component <slot> 簡介

HTML的slot元素,是Web Components技術套件的一部分,是Web組件內的一個占位符,該占位符可以在后期使用自己的標記語言進行填充,這樣可以創建單獨的DOM樹,并將其與其他的組件組合在一起 -- MDN

常見的填充Web組件的shadow DOM的模板有template和slot

  • 模板 - Templates

  • <template id="my-paragraph">
     <p>My paragraph</p>
    </template>
  • let template = document.getElementById('my-paragraph');
    let templateContent = template.content;
    document.body.appendChild(templateContent);
  • 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一起使用,實現純js自定義的組件

    • 需要在網頁上重復的使用相同的標記結構時,為了避免CV的操作可以通過模板的方式進行實現

    • 需要注意的是模板 - Template 和其內部的內容是不會在DOM中呈現的,可以通過js進行訪問并添加到DOM中,從而在界面上進行展示

  • Web Component簡介

    • 類型一:Autonomous custom elements 是獨立的元素,它不繼承其他內建的 HTML 元素,可以直接通過標簽的方式進行HTML使用<popup-info>,也可以通過js的方式進行使用document.createElement("popup-info")

    • 類型二:Customized built-in elements 繼承自基本的 HTML 元素。在創建時,你必須指定所需擴展的元素,使用時,需要先寫出基本的元素標簽,并通過 is屬性指定 custom element 的名稱;<p is="word-count">document.createElement("p", { is: "word-count" })

    • 參數一:表明創建元素的名稱,其注冊的名稱不能簡單的單詞,需要由短劃線進行拼接

    • 參數二:用于定義元素行為的類

    • 參數三:一個包含extends屬性配置的配置對象,可選,指定了所創建的自定義元素是繼承于哪個內置的元素,可以繼承任何內置的元素;

    • customElements.define(
         'word-count',
         WordCount,
         { extends: 'p' }
      );
    • 可以使用ES2015的類實現

    • class WordCount extends HTMLParagraphElement {
       constructor() {
         // 必須首先調用 super 方法
         super();
         // 元素的功能代碼寫在這里
         ...
       }
      }
    • Web Component的一個很重要的屬性就是封裝 - 可以將標記結構、樣式和行為影藏起來,并于界面上的其他代碼隔離開來,保證代碼的獨立性

    • Web Component標準非常重要的一個特性是,使得開發者可以將HTML頁面的功能封住成custom elements(自定義標簽)

    • customElements 接口用來實現一個對象,允許開發者注冊一個custom elements的信息,返回已注冊的自定義標簽的信息;

    • customElements.define方法用來注冊一個custom element,接收三個參數

    • 自定義標簽的類型

      參考文獻 - MDN

  • shadow DOM簡介

    Vue中的插槽、內容分發、具名插槽應用實例分析

    shadow DOM主要是將一個隱藏的、獨立的DOM樹附加到常規的DOM樹上,是以shadow DOM節點為起始根節點,在這個根節點的下方,可以是任意的元素,和普通的DOM元素一致

    • Shadow host:一個常規 DOM 節點,Shadow DOM 會被附加到這個節點上。

    • Shadow tree:Shadow DOM 內部的 DOM 樹。

    • Shadow boundary:Shadow DOM 結束的地方,也是常規 DOM 開始的地方。

    • Shadow root: Shadow tree 的根節點。

    • 圖解Shandow DOM

如常見的video標簽,其內部的一些控制器和按鈕等都是通過Shandow DOM進行維護的,開發者可以通過這個API進行自己獨立的邏輯控制

  • 基本用法

  • let shadow1 = elementRef.attachShadow({mode: 'open'});
    let shadow2 = elementRef.attachShadow({mode: 'closed'});
    let myShadowDom = shadow1.shadowRoot; // 具體內容
    let myShadowDom = shadow2.shadowRoot; //null
  • let shadow = this.attachShadow({mode: 'open'});
    // 將一個shadow DOM添加到一個元素上之后就可以使用DOM API進行操作訪問了
    • 當需要將一個shadow DOM添加到自定義的標簽上時,可以在自定義的構造函數中添加如下邏輯;

    • Element.attachShadow()方法可以將一個shadow DOM添加到任何一個元素上,接收一個配置對象參數,該對象有一個mode的屬性,值可以是open - 可以通過外部js獲取 Shadow DOM和closed - 外部不可以通過js進行獲取 Shadow DOM

以上就是“Vue中的插槽、內容分發、具名插槽應用實例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

vue
AI

凤台县| 涞源县| 根河市| 百色市| 永顺县| 亳州市| 内丘县| 庐江县| 开封市| 萝北县| 开远市| 衡南县| 福海县| 灵山县| 时尚| 芦溪县| 丰宁| 张家口市| 文昌市| 财经| 井陉县| 安远县| 镇平县| 东安县| 锦屏县| 会宁县| 瑞安市| 定南县| 桦甸市| 孝义市| 漳州市| 突泉县| 祁连县| 禹城市| 芜湖市| 绥滨县| 建水县| 厦门市| 敦煌市| 山阴县| 广丰县|