ホームページ  >  記事  >  ウェブフロントエンド  >  Vue のスロット、コンテンツ配布、名前付きスロットについての深い理解

Vue のスロット、コンテンツ配布、名前付きスロットについての深い理解

青灯夜游
青灯夜游転載
2022-10-12 19:43:322095ブラウズ

この記事では、Vue の高度なスキルと、Vue のスロット、コンテンツ配布、名前付きスロットについての深い理解を共有します。皆様のお役に立てれば幸いです。

Vue のスロット、コンテンツ配布、名前付きスロットについての深い理解

スロットの概要

Vue のコンポーネントのデータは、プロップまたはイベントを通じて渡すことができます。ただし、テンプレート コンテンツ (法的なテンプレート コンテンツ、コード スニペット、Vue コンポーネント) を受信する必要がある場合は、スロットを使用してそれを実現する必要があります。もちろん、関数型プログラミングを通じて間接的に実現することもできます。[関連する推奨事項: vuejs ビデオ チュートリアル]

Vue のスロット、コンテンツ配布、名前付きスロットについての深い理解

  • スロットを理解する js で関数をコンパイルする
#
// 父元素传入插槽内容
FancyButton('Click me!')

// FancyButton 在自己的模板中渲染插槽内容
function FancyButton(slotContent) {
    return `<button>
      ${slotContent}
    </button>`
}
  • カプセル化する最良の方法は、共通点をコンポーネントに抽出し、相違点をスロットとして公開することです - 共通点を抽出し、相違点を保持します
  • すべて親コンポーネント テンプレート内のすべては親コンポーネント スコープでコンパイルされ、子コンポーネント テンプレート内のすべては子コンポーネント スコープでコンパイルされます - コンパイル スコープ

スロット スコープの浅い分析

従来のスロットはコンポーネントテンプレートのカスタマイズに使用できますが、固定テンプレートに限定され、特定の内部項目をカスタマイズすることはできない、つまり従来のスロットを実装することはできません。コンポーネント ループ内の項目は、スロット スコープを通じて実装できます。本質的にはスロットと同じです。違いは、パラメーターを渡すことができることです。

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

スロット スコープを使用する場合、親コンポーネントはこの API を使用し、対応するスロットが表示用のテンプレート内のスロットを置き換えます

一般的な API の簡単な分析

名前付きスロット

コンポーネント内で複数のスロット出口を定義すると、複数の異なる要件と互換性があり、出口内で複数のスロットの内容をそれぞれのスロットに渡すことができます。 属性はスロット内に設定されており、そのスロットは名前付きスロットと呼ばれます。名前のないスロットには暗黙的に「デフォルト」という名前が付けられます

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>
スコープ スロット
通常のスロットは、他のスコープ、つまり、親コンポーネント テンプレートの
式のデータを取得できません。親コンポーネントのスコープにのみアクセスできます; 子コンポーネント テンプレートの式は子コンポーネントにのみアクセスできます コンポーネントのスコープは、レンダリング時にデータの一部をスロットに提供するため、子コンポーネントのデータを外部で使用できますコンポーネント (親コンポーネント) -

slot
を介してサブコンポーネントによってスロットに渡されるプロパティは、v- の値として使用されます。 slot ディレクティブ。スロット内の式でアクセスできます。name は Vue によって特別に予約された属性であり、小道具としては使用されません。転送の実行

データ転送<pre class="brush:php;toolbar:false">//子组件 &lt;template&gt;      &lt;slot&gt;&lt;/slot&gt;  &lt;/template&gt;</pre>データ受信

    デフォルトスロット受信
//父组件 - 使用方
<mycom>
  {{ shopInfo }} {{ userInfo }}
</mycom>
    名前付きスロット受信
    • <mycom>
        <template>
          {{ shopInfo }}
        </template>
      
        <template>
          {{ introduction }}
        </template>
      
        <template>
          {{ userInfo }}
        </template>
      </mycom>
    • スロット スコープを使用する場合は、テンプレート内のスロットを最後のスロット スコープに置き換えます
      <cpm>
          <!-- 不显示 -->
          <div>555</div>
          <!-- 不显示 -->
          <div>
              <div>{{scope.name}}</div>
          </div>
          <!-- 显示 -->
          <div>
              <div>{{scope}}</div>
              <div>{{scope.name}}</div>
              <div>{{scope.age}}</div>
          </div>
      </cpm>
    • スコープ スロットを使用する場合、サブコンポーネント スロットを再利用してスロットの内容を作成できます一貫性がありません。ユーザーは、既にレンダリングされた要素の代わりにテンプレートをスロットに渡すことができます。いわゆるスコープはテンプレートを指します。親スコープ内でレンダリングされますが、子コンポーネントのデータを取得できます。 従来の v-bind は、送信のためにパラメータ キー値を運ぶ必要があります (例:
    • v-bind:info = '123 '
    • ;)。しかし、このキー値が省略されてデータが直接転送される場合があります。 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属性
        • 需要有一个明确的结束条件
      <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>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 中国語 Web サイトの他の関連記事を参照してください。

      声明:
      この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。