オリジナル住所:https://www.jianshu.com/p/e10baeff888d
序文
インターネットは、私はそれがまたスロットスコープのための私自身を共有し、この問題、に触れますコンポーネントの深い理解を持つべきだと思う、それの非常に特定の感覚を書いていない、スロットの範囲についての説明の多くを検索しますほとんど理解。
- 我々はピット内に何かが親コンポーネントによって決定されます置くサブアセンブリの穴を、文書のノウハウのすべてを見ていない、と掘る以外の何物でもスロット。
// サブアセンブリ <テンプレート> <スロット>ああ、私は穴掘ってきました。</スロット> </テンプレート> // 親要素 <テンプレート> <子ども> <! -カスタマイズの着信サブアセンブリ、サブアセンブリのスロットスロットを記入します- > <スパン>私は、コンポーネントを置くために、そして、喜んで、このスパンに入れOK </ span>にある </子> </テンプレート>
- 入ってくるプレーンテキストをスロットに
- パスイメージングコンポーネントをスロットに
- 親コンポーネント、サブアセンブリは間違いなくいくつかのスロットを区別したいと命名スロット私は親コンポーネントを決定することながら、プロパティ・スロットを識別する名前タグを使用し、そのような複数のスロットとして、また、非常に簡単です何を入れているどのようなスロットは、対応するスロットに渡されたスロット属性名に値を割り当てる必要があります。名前のない属性スロット場合は、スロットが匿名である親コンポーネントは、コンテンツ属性スロットが指定されていませんが、それは匿名のスロットにスローされます。
// サブアセンブリ <テンプレート> <節> <スロット名= "Articleこの記事だったタイトル">ここに置かタイトル</スロット> <スロット>ここに置か著者</スロット> <スロット名= "この記事だったのContent-条">ここに置か記事コンテンツ</スロット> </部> </テンプレート> // 親要素 <テンプレート> <節> <スロット子> <H1スロット= "Articleこの記事は、タイトルだった"> VUEスコープスロット、あなたが本当にまだ理解?</ H1> <P-スロット= "この記事だったのContent-記事は">ビットは理解しているようだ。</ p型> の<div>王ウー</ DIV> </スロット子> </部> </テンプレート>
- これは、スロットの範囲を理解することが最も困難です。また、おそらく言ったスロットの範囲内で、親がデータコンポーネントサブアセンブリを得ることができ、少しめまいかもしれ友人のマニュアルを参照してください。:サブアセンブリのような、スロットラベルのプロパティ値にバインドすることができます
<スロット:ニックネーム= " 'Tusi'"> </スロット>
ニックネームは、結合スロット範囲によって親要素オブジェクトの値を取得します。
<テンプレート> <セクション> <スロット子> <テンプレートスロットスコープ= "範囲"> の<div> {{scope.nickName}} </ div> </テンプレート> </スロット子> </セクション> < /テンプレート>
ここでは、疑いも持っている必要があります。用途は何ですか?私は$発する親コンポーネントとサブアセンブリにデータを転送リストに載っていないのですか?
スロットの範囲のほとんど理解
私はシナリオのスコープスロットを考えるようにコンポーネント間のデータフローからだと思います。
どのようにあなたのだろう、最初のシナリオは、あなたが複数のカードを表示するには、組立商品カードを書き、ループをする必要があると仮定し、製品の詳細ページへカードまたはその他のコンテンツのクリックイベントとジャンプの各ピクチャの要件に応えることができます書くのか?
私はV-用カードリスト取り扱う商品の表示で、次の最初の商品カードアセンブリCommodity.vueとして書かれたアプローチ、およびCommodityList.vueに使用されます。
<commodity v-for="(item,index) in commodities" @clickCommodity="onCommodityClick"></commodity>
Commodity组件通过$emit像父组件传递clickCommodity事件,并携带商品数据,父组件即可在onCommodityClick方法中得到数据,进行业务处理,这样便完成了一个基本的由子到父的数据传递。
如果再往上抽象一下呢?比如我有多个运营栏目,像淘宝首页有“有好货”,“爱逛街”这样两个栏目,每个栏目下都需要有一个商品卡片列表,那么商品卡片列表CommodityList.vue就要抽成组件了。而这个包含多个运营栏目的vue组件我假设它叫ColumnList.vue,在其中通过v-for调用了CommodityList组件。
注意:业务来了,我希望把点击商品卡片的业务放在ColumnList.vue中处理。你们想象一下要怎么做?一种土办法就是商品按钮点击时,Commodity组件$emit通知CommodityList.vue,而CommodityList接着把事件用$emit往上抛,那么ColumnList.vue就能处理这个点击事件了。这样做完全没有问题,但是显得子组件很不纯粹,跟业务都扯上关系了。
那么如何优雅地解决这个问题呢?这个时候,作用域插槽真正派上用场了。
通过作用域插槽将本应该由CommodityList处理的商品卡片点击业务onCommodityClick提升到ColumnList处理。
<el-row :gutter="20"> <el-col :span="12" v-for="(column, index) in columnList" :key="index"> <el-card class="box-card card-column"> <div slot="header" class="clearfix"> <span>{{column.columnName}}</span> </div> <commodity-list :commodities="column.commodityList"> <template slot-scope="scope"> <!-- 这里只需要给Commodity组件传入数据,响应Commodity组件的clickCommodity事件即可。 事件不必携带参数,完全符合父到子的数据流向,而不会发生子组件又给父组件反向发数据的情况 --> <commodity :modityData="scope.row" @clickCommodity="onCommodityClick(scope.row)"></commodity> </template> </commodity-list> </el-card> </el-col> </el-row>
而CommodityList组件内部应该是改造成这样,slot接收来自父组件的商品卡片组件,这里面不涉及关于商品组件的业务,只关注其他业务和布局即可。最终就实现了组件和业务的剥离,这也是组件化的精髓所在吧。不知道有没有帮到您呢?
<el-row :gutter="20">
<el-col :span="8" v-for="(item, index) in commodities" :key="index" style="margin-top:20px;">
<slot :row="item"></slot>
</el-col>
</el-row>
这是我实现的效果,忽略样式吧,原理都懂了,做个漂亮的卡片有多难?
总结一下,作用域插槽适合的场景是至少包含三级以上的组件层级,是一种优秀的组件化方案!
欢迎小伙伴们来踩我的主页