自定義組件--內(nèi)部&全局&slot插槽

自定義組件:
在開(kāi)發(fā)中,為了代碼的重用,我們常常會(huì)把一個(gè)公用的部分,抽象成一個(gè)組件;這樣,這個(gè)組件就可以再多個(gè)地方重復(fù)使用

  1. 理解: 用來(lái)實(shí)現(xiàn)局部(特定)功能效果的代碼集合(html/css/js/image…..)
  2. 為什么: 一個(gè)界面的功能很復(fù)雜
  3. 作用: 復(fù)用編碼, 簡(jiǎn)化項(xiàng)目編碼, 提高運(yùn)行效率

Vue中使用組件的三大步驟:
一、定義組件(創(chuàng)建組件)
二、注冊(cè)組件
三、使用組件(寫(xiě)組件標(biāo)簽)

一、如何定義一個(gè)組件?
使用Vue.extend(options)創(chuàng)建,其中options和new Vue(options)時(shí)傳入的那個(gè)options幾乎一樣,但也有點(diǎn)區(qū)別;
區(qū)別如下:
1.el不要寫(xiě),為什么? ——— 最終所有的組件都要經(jīng)過(guò)一個(gè)vm的管理,由vm中的el決定服務(wù)哪個(gè)容器。
2.data必須寫(xiě)成函數(shù),為什么? ———— 避免組件被復(fù)用時(shí),數(shù)據(jù)存在引用關(guān)系。
備注:使用template可以配置組件結(jié)構(gòu)。

二、如何注冊(cè)組件?
1.局部注冊(cè):靠new Vue的時(shí)候傳入components選項(xiàng)
2.全局注冊(cè):靠Vue.component('組件名',組件)

三、編寫(xiě)組件標(biāo)簽:
<b-box></b-box>

自定義內(nèi)部組件:

<style>
       *{
           margin: 0;
           padding: 0;
       }
       .box{
           width: 300px;
           border: 1px solid #ccc;
           padding: 5px;
           margin: 5px;
           color: #333;
           float: left;
       }
       .box h2{
           font-size: 20px;
           text-align: center;
       }
       .box .content{
           font-size: 14px;
           border-top: 1px solid #eee;
           margin-top: 5px;
           padding-top: 5px;
       }
   </style>
<!-- 準(zhǔn)備好一個(gè)容器-->
<div id="app">
<!-- 第三步:編寫(xiě)組件標(biāo)簽 -->
        <b-box v-for="(item,index) in list" :key="index" :title="item.title" :content="item.content"></b-box>
 </div>
<script>
        let vm = new Vue({
          //指定Vue實(shí)例掛載的容器
            el: '#app',
            components: {
                'b-box': {
                    //組件的模板
                    template: `
                    <div>
                    //使用template選項(xiàng),定義組件的模板,注意:模板中必須包含一個(gè)根標(biāo)簽
                        <div class='list' v-for="(item,index) in list">
                                <h2 >{{item.title}}</h2>
                                <p >{{item.content}}</p>
                         </div>
                     </div>
                   `,
                 //定義組件的屬性,注意:必須要用''
                    props: ['list']
                }

            },
            // 注意:Vue實(shí)例的data選項(xiàng)可以是一個(gè)對(duì)象,也可以是一個(gè)方法,由該方法返回一個(gè)對(duì)象
            // 但是在組件中,data選項(xiàng)必須是一個(gè)方法,由該方法返回一個(gè)對(duì)象
            // 因?yàn)榻M件可能會(huì)使用很多次,如果data選項(xiàng)是對(duì)象的話,會(huì)導(dǎo)致多個(gè)組件使用了同一份數(shù)據(jù)。
            data() {
                return {
                    list: [{
                        title: '奔馳',
                        content: '梅賽德斯-奔馳(Mercedes-Benz)是世界聞名的豪華汽車(chē)品      牌。1886年1月,卡爾·本茨發(fā)明了世界上第一輛三輪汽車(chē),獲得專利(專利號(hào):DRP 37435 [1] ),被譽(yù)為“汽車(chē)的發(fā)明者”。'
                    },

                    {
                        title: '寶馬',
                        content: '寶馬(BMW),中文全稱為巴伐利亞發(fā)動(dòng)機(jī)制造廠股份有限公司,德國(guó)汽車(chē)品牌,寶馬的車(chē)系有i、X、Z、純數(shù)字4個(gè)車(chē)型,1、2、3、4、5、6、7、8等幾個(gè)系列,還有在各系基礎(chǔ)上進(jìn)行改進(jìn)的M系(寶馬官方的高性能改裝部門(mén)',
                    },
                    {
                        title: '奧迪',
                        content: '德國(guó)豪華汽車(chē)品牌,其標(biāo)志為四個(gè)圓環(huán)相扣?,F(xiàn)為德國(guó)大眾汽車(chē)公司的子公司。2018年12月20日,2018世界品牌500強(qiáng)排行榜發(fā)布,奧迪位列51位。'
                    }
                    ]
                };
            }
        })
    </script>

自定義全局組件

<div id='app'>
        <b-goods :name='name' :count='count'></b-goods>
    </div>
 <script>
        Vue.component('b-goods', {
            template: `
                <div class=box>
                    {{name}}:
                    <button @click='mycount--' :disabled='mycount===1'>-</button>
                    <input type="text" v-model='mycount'>
                    <button @click='mycount++'>+</button>
                </div>`,
                //props選項(xiàng),用于定義組件的屬性,有兩種方式:1.定義數(shù)組,2.定義對(duì)象
               //注意:props是只讀的,不能修改所以需要在data里重新定義一個(gè)值用來(lái)接收
               //用于父組件給子組件傳遞數(shù)據(jù)
            // props: ['name','count'],
            props:{
                name:{
                    type:String
                },
                count:{
                    type:Number,
                    default:1
                }
            },
            data() {
                return {
                    mycount:this.count
                }
            }
        })
        Vue.config.productionTip = false
        let vm = new Vue({
            el: '#app',
            components: {},
            data() {
                return {
                    name:'衣服',
                    count:1
                };
            }
        })
    </script>

slot插槽
插槽的主要作用是幫助我們更好的在其他組件中進(jìn)行布局。當(dāng)想要便攜可重用的控件時(shí)尤為重要。

適用場(chǎng)景:
在自定義編寫(xiě)組件時(shí),多個(gè)組件里面的內(nèi)容不完全相同時(shí),如果瘋狂使用v-show或者v-if來(lái)控制不同的組件展示不同的內(nèi)容會(huì)有些許的麻煩,插槽就相當(dāng)于是在父組件頁(yè)面中的子組件標(biāo)簽里面編寫(xiě)一段代碼,然后這段代碼會(huì)被插入到子組件里面,但是子組件本身是有dom元素的,所以插入的時(shí)候需要根據(jù)slot標(biāo)簽的位置來(lái)決定插入的位置,又或者是根據(jù)slot的名稱來(lái)確定。

<style>
        *{
            margin: 0;
            padding: 0;
            list-style: none;
        }
        .tab{
            width: 400px;
            border: 1px solid #ccc;
            padding: 5px;
            margin: 10px;
            overflow: hidden;
        }
        .tab .titles{
            display: flex;
        }
        .tab .titles li{
            border: 1px solid #ccc;
            padding: 2px 10px;
            margin: 0 2px;
            cursor: pointer;
        }
        .tab .titles li.active{
            background-color: orangered;
            color:white;
        }
        .tab .contents{
            padding: 5px;
            border: 1px solid #ccc;
            margin: 4px 2px;
        }
    </style>
<div id="app">
        <b-tab :list="list" :active="activeIndex">
            <H2>全國(guó)著名小吃</H2>
        </b-tab>
    </div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.js"></script>
    <script>
        Vue.config.productionTip = false
        // 組件組件
        Vue.component('b-tab', {
            template:`
            <div class="tab">
                <slot></slot>
                <ul class="titles">
                    <li @click="activeIndex=index" :class="{active:activeIndex===index}" v-for="(item,index) in list" :key="index">{{item.title}}</li>
                </ul>
                <ul class="contents">
                    <li v-show="activeIndex===index" v-for="(item,index) in list" :key="index">{{item.content}}</li>
                </ul>
            </div>
            `,
            props:['list','active'],
            data() {
                return {
                    activeIndex:this.active
                }
            },
        })
        new Vue({
            el:'#app',
            data:{
                //高亮索引
                activeIndex:0,
                list:[
                    {
                        title:'北京',
                        content:'北京的糖葫蘆真好吃'
                    },
                    {
                        title:'南京',
                        content:'南京的鹽水鴨真好吃'
                    },
                    {
                        title:'武漢',
                        content:'武漢的熱干面真好吃'
                    },
                    {
                        title:'長(zhǎng)沙',
                        content:'長(zhǎng)沙的臭豆腐真好吃'
                    }
                ]
            }
        })
    </script>

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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