ホームページ >ウェブフロントエンド >フロントエンドQ&A >vue スロットはどのような問題を解決しますか?

vue スロットはどのような問題を解決しますか?

青灯夜游
青灯夜游オリジナル
2023-01-13 18:26:512324ブラウズ

vue スロットによって解決される問題: 導入されたサブコンポーネント タグの途中にコンテンツを書き込むことはできません。スロットは、コンポーネント パッケージャ用に Vue によって提供される機能です。開発者は、コンポーネントをパッケージ化するときに、ユーザーがスロットとして指定すると予想される不確実な部分を定義できます。スロットは、コンポーネントのパッケージ化中と見なすことができます。ユーザー用に予約されたコンテンツのプレースホルダー。

vue スロットはどのような問題を解決しますか?

#このチュートリアルの動作環境: Windows7 システム、vue3 バージョン、DELL G3 コンピューター。

#スロットとは何ですか? vue では、導入されたサブコンポーネント タグの途中にコンテンツを記述することはできないことがわかっています。この問題を解決するために、公式はスロットの概念を導入しました。

スロットは実際にはプレースホルダーと同等です。これにより、コンポーネント内で HTML テンプレートに場所が与えられ、いくつかのものを渡すことができるようになります。スロットは、

匿名スロット

名前付きスロット、およびスコープ付きスロットに分割されます。 なぜ HTML をサブコンポーネントに直接記述するのではなく、サブコンポーネントに渡す必要があるのか​​よく理解できないかもしれません。答えはこれです。 5 ページあるシナリオを想像してみてください。5 ページのうち 1 つの領域だけが異なるコンテンツを持っています。この 5 ページはどのように書きますか?コピー アンド ペーストも 1 つの方法ですが、vue ではスロットの方が優れています。

vue スロットはどのような問題を解決しますか?

##匿名スロット匿名スロット。単一スロット スロットまたはデフォルトと呼ぶことができます。スロット。名前付きスロットとは異なり、name 属性を設定する必要はありません。 (隠れた name 属性がデフォルトです。)


例:

ファイルディレクトリは次のとおりで、Home コンポーネントが HelloWorld の親コンポーネントです。

vue スロットはどのような問題を解決しますか?HelloWorld に匿名スロットを作成します

    <template>
      <div>
         Helloworld组件
    
         <div>
           <slot></slot>
         </div>
    
      </div>
    </template>
    
    <script>
    export default {
    
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style>
    .hello{
      width:100%;
      height:300px;
      background:#ccc;
      margin-top:50px;
      .slotTxt{
        width:500px;
        height:200px;
        margin:30px auto;
        background:red;
      }
    }
    </style>
  • Home コンポーネントにサブコンポーネントを導入し、サブコンポーネントに追加します。コンポーネント コンポーネントタグに書かれた内容 #
    <template>
      <div>
        我是Home父组件
        <helloworld>
          <!-- 没有插槽,这里的内容不显示 -->
          <h1>我是helloworld中的插槽啊</h1>  
        </helloworld>
      </div>
    </template>
    
    <script>
    import HelloWorld from &#39;@/components/HelloWorld.vue&#39;
    export default {
      name: &#39;home&#39;,
      components: {
        HelloWorld
      }
    }
    </script>
      Effect

    HelloWorld タグ内の内容 (赤い部分) を見るのは難しくありません。が表示されました。

    vue スロットはどのような問題を解決しますか?

    名前付きスロット

    前述したように、スロットには名前属性があります。匿名スロットとは対照的に、name 属性が追加された匿名スロットは名前付きスロットです。


    HelloWorld コンポーネントに name 属性が left と right のスロットをそれぞれ書き込みます

    <template>
      <div>
         Helloworld组件
    
         <div>
           <slot></slot>
         </div>
    
         <div>
           <slot></slot>
         </div>
    
      </div>
    </template>
    
    <script>
    export default {
    
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style>
    .hello{
      width:700px;
      height:300px;
      background:#ccc;
      margin: 0 auto;
      margin-top:50px;
      .slotLeft{
        width:300px;
        height:200px;
        float:left;
        background:red;
      }
      .slotRight{
        width:300px;
        height:200px;
        float:right;
        background:pink;
      }
    }
    </style>
    • Home コンポーネントはテンプレートに v-slot:name を書き込みnamed を使用しますスロット
    <template>
      <div>
        我是Home父组件
        <helloworld>
          <template>
             <h1>name属性为left</h1> 
          </template>
          <template>
             <h1>name属性为right</h1> 
          </template>
         
        </helloworld>
      </div>
    </template>
    
    <script>
    import HelloWorld from &#39;@/components/HelloWorld.vue&#39;
    export default {
      name: &#39;home&#39;,
      components: {
        HelloWorld
      }
    }
    </script>
    <style>
    .home{
      width:900px;
      margin:0 auto;
      background:yellow;
      padding-bottom:100px;
    }
    </style>
    • v-slot はテンプレート タグにのみ追加できることに注意してください (1 つの例外を除く)。

    #影響

    • ##例外 (放棄されたスロット='名前')
    スロット属性を持つ名前付きスロットは 2.6.0 以降廃止され、vue3.x は完全に廃止されました。 vue3 以前の cli のみ使用可能です。

    vue スロットはどのような問題を解決しますか?

    <template>
      <div>
        我是Home父组件
        <helloworld>
          <h1>name属性为left</h1>  
          <h1>name属性为right</h1>  
        </helloworld>
      </div>
    </template>
    
    <script>
    import HelloWorld from &#39;@/components/HelloWorld.vue&#39;
    export default {
      name: &#39;home&#39;,
      components: {
        HelloWorld
      }
    }
    </script>
    <style>
    .home{
      width:900px;
      margin:0 auto;
      background:yellow;
      padding-bottom:100px;
    }
    </style>
    効果は上記と同じです。

    • 名前付きスロットに関するほとんどの知識
    • v-on や v-bind と同様、v-slot にも省略形があります。つまり、パラメーター (v-slot:) より前のすべてを文字に置き換えます。 #。たとえば、v-slot:header は #header に書き換えることができます。

    • #スコープ スロット

    スコープ スロットは、実際にはデータを渡すことができるスロットです。子コンポーネント内の一部のデータを親コンポーネントで使用する場合は、指定されたメソッドを介してデータを渡す必要があります。公式ドキュメントでは、**親テンプレート内のすべてのコンテンツが親スコープでコンパイルされるというルールが提案されています。子テンプレート内のすべては子スコープでコンパイルされます。 **子コンポーネントの値を親コンポーネントで直接使用すると、エラーが報告されます。 匿名スロットのスコープ スロット


    子コンポーネントのデータを親のスロット コンテンツで利用できるようにするには、そのデータを要素の A プロパティとして使用できます。バインドされています:

    语法:v-bind:users="user"

    サブコンポーネント HelloWorld コード

    <template>
      <div>
         Helloworld组件  
         <div>
           <slot></slot>
         </div> 
         
      </div>
    </template>
    
    <script>
    export default {
      data(){
        return{
          user:{
            name:&#39;oralinge&#39;,
            age:18
          }
        }  
      }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style>
    .hello{
      width:700px;
      height:300px;
      background:#ccc;
      margin: 0 auto;
      margin-top:50px;
      .slotLeft{
        width:300px;
        height:200px;
        // float:left;
        background:red;
        margin:20px auto
      }
      .slotRight{
        width:300px;
        height:200px;
        float:right;
        background:pink;
      }
    }
    </style>
    要素 (v-bind:users="user") にバインドされたプロパティが、スロット プロパティに対して呼び出されます。これで、親スコープで、v-slot を値とともに使用して、提供するスロット プロパティの名前を定義できるようになりました。

    语法:v-slot:default="随意取的名字"  // default可省略,简写为v-slot="随意取的名字"
      親コンポーネントのホームコード
    <template>
      <div>
        我是Home父组件
        <helloworld>
          <template>
             <h1>{{slotProps.users.name}}</h1> 
          </template>
        </helloworld>
      </div>
    </template>
    
    <script>
    import HelloWorld from &#39;@/components/HelloWorld.vue&#39;
    export default {
      name: &#39;home&#39;,
      components: {
        HelloWorld
      }
    }
    </script>
    <style>
    .home{
      width:900px;
      margin:0 auto;
      background:yellow;
      padding-bottom:100px;
    }
    </style>
    注:

    親コンポーネントのslotPropsは自由に取得できます。

    サブコンポーネントのユーザーは、親コンポーネントのユーザーに対応して、任意に選択されます。
      サブコンポーネント内のユーザーはデータです。
    • 効果




    名前付きスロットのスコープ スロット

    匿名スロットと同じ、自分だけデフォルトをスロットの名前の値に置き換える必要があります。 vue スロットはどのような問題を解決しますか?

    サブコンポーネント HelloWorld コード

    <template>
      <div>
         Helloworld组件  
         <div>
           <slot></slot>
         </div> 
         
      </div>
    </template>
    
    <script>
    export default {
      data(){
        return{
          user:{
            name:&#39;hello world&#39;,
            age:18
          }
        }  
      }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style>
    .hello{
      width:700px;
      height:300px;
      background:#ccc;
      margin: 0 auto;
      margin-top:50px;
      .slotLeft{
        width:300px;
        height:200px;
        // float:left;
        background:red;
        margin:20px auto
      }
      .slotRight{
        width:300px;
        height:200px;
        float:right;
        background:pink;
      }
    }
    </style>

    親コンポーネント ホームコード

      <template>
        <div>
          我是Home父组件
          <helloworld>
            <template>
               <h1>{{slotProps.users.name}}</h1> 
            </template>
          </helloworld>
        </div>
      </template>
      
      <script>
      import HelloWorld from &#39;@/components/HelloWorld.vue&#39;
      export default {
        name: &#39;home&#39;,
        components: {
          HelloWorld
        }
      }
      </script>
      <style>
      .home{
        width:900px;
        margin:0 auto;
        background:yellow;
        padding-bottom:100px;
      }
      </style>
    • Effect
    • vue スロットはどのような問題を解決しますか?

      注意:
           默认插槽的缩写语法不能和具名插槽混用,因为它会导致作用域不明确。

      vue スロットはどのような問題を解決しますか?

      另,slot-scope写法在2.6之后已废弃,作用与上面相同,在此不做解释。

      上面的写法是不是觉得有些麻烦?别着急,我们来看一看解构插槽 Prop

      解构插槽 Prop

      作用域插槽的内部工作原理是将你的插槽内容包括在一个传入单个参数的函数里:

      function (slotProps) {
        // 插槽内容
      }

      这意味着 v-slot 的值实际上可以是任何能够作为函数定义中的参数的 JavaScript 表达式。所以在支持的环境下 (单文件组件或现代浏览器),你也可以使用 ES2015 解构来传入具体的插槽 prop。

      语法:v-slot="{ users }"
      • HelloWold组件
      <template>
        <div>
           Helloworld组件  
           <div>
             <slot></slot>
           </div> 
           
        </div>
      </template>
      
      <script>
      export default {
        data(){
          return{
            user:{
              name:&#39;hello world&#39;,
              age:18
            }
          }  
        }
      }
      </script>
      
      <!-- Add "scoped" attribute to limit CSS to this component only -->
      <style>
      .hello{
        width:700px;
        height:300px;
        background:#ccc;
        margin: 0 auto;
        margin-top:50px;
        .slotLeft{
          width:300px;
          height:200px;
          // float:left;
          background:red;
          margin:20px auto
        }
        .slotRight{
          width:300px;
          height:200px;
          float:right;
          background:pink;
        }
      }
      </style>
      • Home组件
      <template>
        <div>
          我是Home父组件
          <helloworld>
            <template>
               <h1>{{users.name}}</h1> 
            </template>
          </helloworld>
        </div>
      </template>
      
      <script>
      import HelloWorld from &#39;@/components/HelloWorld.vue&#39;
      export default {
        name: &#39;home&#39;,
        components: {
          HelloWorld
        }
      }
      </script>
      <style>
      .home{
        width:900px;
        margin:0 auto;
        background:yellow;
        padding-bottom:100px;
      }
      </style>
      • 效果

      vue スロットはどのような問題を解決しますか?

      • 重命名----更改users这个名字
      <template>
        <div>
          我是Home父组件
          <helloworld>
            <template>
               <h1>{{person.name}}</h1> 
            </template>
          </helloworld>
        </div>
      </template>
      
      <script>
      import HelloWorld from &#39;@/components/HelloWorld.vue&#39;
      export default {
        name: &#39;home&#39;,
        components: {
          HelloWorld
        }
      }
      </script>
      <style>
      .home{
        width:900px;
        margin:0 auto;
        background:yellow;
        padding-bottom:100px;
      }
      </style>

      效果如上图。

      • 定义后备内容,用于插槽 prop 是 undefined 的情形
        此处按照官方文档的写法会出现语法报错,后期应该会修复(有知道的麻烦通知一声)。
      <template>
        <div>
          我是Home父组件
          <helloworld>
            <template>
               <h1>{{users.name}}</h1> 
            </template>
          </helloworld>
        </div>
      </template>
      
      <script>
      import HelloWorld from &#39;@/components/HelloWorld.vue&#39;
      export default {
        name: &#39;home&#39;,
        components: {
          HelloWorld
        }
      }
      </script>
      <style>
      .home{
        width:900px;
        margin:0 auto;
        background:yellow;
        padding-bottom:100px;
      }
      </style>

      使用场景


      • 复用公共组件
        代码示例如下:
      <template>
        <div>
          <div>
            <span>{{title}}</span>
            <div>
              <slot></slot>
            </div>
          </div>
          <div>
            <slot></slot>
          </div>
        </div>
      </template>
      <script>
      export default {
        data () {
          return {
          }
        },
        props: {
          title: {
            type: String,
            required: true
          }
        }
      }
      </script>
      <style>
      .title-box {
        padding: 16px 0;
        border-bottom: 1px solid #eff1f5;
        .title {
          font-family: MicrosoftYaHei;
          font-size: 24px;
          color: #283039;
          letter-spacing: 0;
          line-height: 24px;
          &::before {
            width: 4px;
            margin-right: 20px;
            content: "";
            background-color: #5da1ff;
            display: inline-block;
            height: 20px;
            vertical-align: middle;
          }
        }
        .right {
          float: right;
          margin-right: 20px;
        }
      }
      </style>

      使用的ui框架为ivew。

      相关推荐:vue.js视频教程

      以上がvue スロットはどのような問題を解決しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

      声明:
      この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。