Vue 組件 / 插槽

編譯作用域
<child-component>
{{message}}
</child-component>
<!--在這里,{{massage}}的數(shù)據(jù)應(yīng)該是父組件的數(shù)據(jù),而不是child-componet的數(shù)據(jù)-->

在vue組件中作用域簡單的說就是:

父組件模板的內(nèi)容在父組件的作用域內(nèi)編譯,子組件模板的內(nèi)容在子組件的作用域內(nèi)編譯

一個常見的錯誤是我們會試圖在父組件內(nèi)將一個指令綁定到子組件的屬性/方法

<child-component v-show="someChildProperty"></child-component>

如果someChildProperty是子組件的屬性,那么這種做法是無效的,在vue中父模板是不應(yīng)該知道子組件狀態(tài)的,如果想要通過子組件的someChildProperty來控制子組件的show/hide,那么應(yīng)該在子組件內(nèi)對其進(jìn)行設(shè)置

單個插槽

在我們使用組件時,父組件在子組件標(biāo)簽內(nèi)寫入的內(nèi)容都會被丟棄,例如

<child-component>
    <p>父組件的內(nèi)容</p>  <!--不會顯示-->
</child-component>

如果我們想要在子組件渲染時能夠渲染出父組件添加的內(nèi)容,需要為子組件組件中設(shè)置slot插槽

當(dāng)子組件內(nèi)只有一個沒有屬性的插槽時,父組件在調(diào)用子組件時在子組件內(nèi)添加的內(nèi)容將全部插入到插槽所在的DOM節(jié)點的位置,并替換掉插槽標(biāo)簽本身

最初在插槽標(biāo)簽內(nèi)的任何元素都將會被視為默認(rèn)內(nèi)容,默認(rèn)內(nèi)容在子組件的作用域內(nèi)編譯,只有在宿主元素為空,且沒有插入內(nèi)容的時候才顯示

<body>
<div id="box">
    <h4>This's parent</h4>
    <child>
        <h4>推薦好友列表</h4>
        <ul>
            <li>tom</li>
        </ul>
    </child>
</div>
<template id="childTem">
    <div>
        <h4>This's child</h4>
        <slot>
            <p>您還沒有推薦好友~</p>
        </slot>
    </div>
</template>
<script>
   new Vue({
       components:{
           'child':{
               template:"#childTem"
           }
       }
   }).$mount("#box")
</script>
</body>
具名插槽

slot元素可以用一個特殊的屬性name來配置如何分布內(nèi)容,多個插槽可以有不同的名字,設(shè)置有name屬性的插槽會匹配到父組件中具有相同值的具有slot屬性的元素

仍然可以有匿名的插槽,它會作為默認(rèn)插槽存在,在插槽找不到匹配的slot值或不具有name的插槽會被插入到匿名的插槽中

<body>
<div id="box">
    <h2>具名插槽</h2>
    <child>
        <h4 slot="header">{{parentMsg}}</h4>
        <p>Test</p>
        <div>
            <p>1.父組件數(shù)據(jù)</p>
            <p>2.展示slot使用方法</p>
        </div>
        <h6 slot="footer">parentFooter</h6>
    </child>
</div>
<template id="childTem">
    <div>
        <header>
            <slot name="header"></slot>
        </header>
        <main>
            <slot></slot>
        </main>
        <footer>
            <slot name="footer"></slot>
        </footer>
    </div>
</template>
<script>
    new Vue({
        data: {
            parentMsg: 'parentHeader'
        },
        components: {
            'child': {
                template: '#childTem'
            }
        }
    }).$mount('#box')
</script>
</body>
作用域插槽

+2.1.0新增

作用域插槽是一種特殊類型的插槽,可以用來將子組件的數(shù)據(jù)展示到slot插槽中

在子組件中,只需要將數(shù)據(jù)傳遞到插槽,就像我們將props傳遞給組件一樣,格式為

<slot :text="變量值"></slot>
<!--text是我們自定義的變量名,:表示是動態(tài)的,變量值為我們要從子組件中傳遞的數(shù)據(jù)-->

在父級中,具有特殊屬性的的scope的template元素必須存在,表示這是作用域插槽的模板,scope的值對應(yīng)一個臨時變量名,此變量接收從子組件中傳遞的props對象,格式為:

<child>
  <template slot-scope="props">
    <!--props是我們自定義的名稱-->
    <span>{{props}}</span>
    <!--props會接收所有的slot上傳遞的變量值,并將其合成為一個對象,如上面的例子,打印props會得到
    {text:變量值}
    -->
  </template>
</child>

在2.5.0之后的版本官方用slot-scope替換了scope

<body>
<div id="box">
    <child>
        <template  slot-scope="props" slot="test">
            <li>{{props.item.name}}</li>
            <li>{{props.item.age}}</li>
        </template>
    </child>
</div>
<template id="childTem">
    <ul>
        <slot
              name="test"
              v-for="item in items"
              :item="item"
        ></slot>
    </ul>
</template>
<script>
    new Vue({
        components: {
            "child": {
                template: "#childTem",
                data() {
                    return {
                        items: [
                            {
                                name: 'xm',
                                age: 18
                            }
                        ]
                    }
                }
            }
        }
    }).$mount("#box")
</script>
</body>

這種用法在我們使用Element時非常常見,例如在使用表格組件時需要根據(jù)后臺返回的1、2、3展示對應(yīng)狀態(tài)已完成、未完成、已駁回

<el-table-column
        label="狀態(tài)"
        minWidth="150">
        <template slot-scope="scope">
           <span v-if="scope.row.state==1">已完成</span>
           <span v-else-if="scope.row.state==2">未完成</span>
           <span v-else @click="turn" class="turn">已駁回</span>
        </template>
</el-table-column>

在使用slot-scope時,支持es 6 的對象解構(gòu)語法,例如上面的例子,我們可以改寫為

<el-table-column
        label="狀態(tài)"
        minWidth="150">
        <template slot-scope="{row}">
           <span v-if="row.state==1">已完成</span>
           <span v-else-if="row.state==2">未完成</span>
           <span v-else @click="turn" class="turn">已駁回</span>
        </template>
</el-table-column>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 此文基于官方文檔,里面部分例子有改動,加上了一些自己的理解 什么是組件? 組件(Component)是 Vue.j...
    陸志均閱讀 3,955評論 5 14
  • 什么是組件 組件(Component)是 Vue.js 最強大的功能之一。組件可以擴展 HTML 元素,封裝可重用...
    angelwgh閱讀 821評論 0 0
  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內(nèi)容,還有我對于 Vue 1.0 印象不深的內(nèi)容。關(guān)于...
    云之外閱讀 5,187評論 0 29
  • 肖洪濤是水果O2O公司調(diào)果師CEO,曾經(jīng)從事公關(guān)行業(yè)十余年。在接受舵舟采訪時,她分享了自己創(chuàng)業(yè)的心得體會。在肖洪濤...
    f1055068a104閱讀 334評論 0 0
  • 我在隱藏一個秘密 一個不能說出來的秘密 它如此美好,卻不能說出口 我痛苦地捧著它 可內(nèi)心卻又是歡喜的。 我時而皺眉...
    藍(lán)色公主閱讀 298評論 0 0

友情鏈接更多精彩內(nèi)容