自定义组件--内部&全局&slot插槽

自定义组件:
在开发中,为了代码的重用,我们常常会把一个公用的部分,抽象成一个组件;这样,这个组件就可以再多个地方重复使用

  1. 理解: 用来实现局部(特定)功能效果的代码集合(html/css/js/image…..)
  2. 为什么: 一个界面的功能很复杂
  3. 作用: 复用编码, 简化项目编码, 提高运行效率

Vue中使用组件的三大步骤:
一、定义组件(创建组件)
二、注册组件
三、使用组件(写组件标签)

一、如何定义一个组件?
使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样,但也有点区别;
区别如下:
1.el不要写,为什么? ——— 最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。
2.data必须写成函数,为什么? ———— 避免组件被复用时,数据存在引用关系。
备注:使用template可以配置组件结构。

二、如何注册组件?
1.局部注册:靠new Vue的时候传入components选项
2.全局注册:靠Vue.component('组件名',组件)

三、编写组件标签:
<b-box></b-box>

自定义内部组件:

<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>
<!-- 准备好一个容器-->
<div id="app">
<!-- 第三步:编写组件标签 -->
        <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实例挂载的容器
            el: '#app',
            components: {
                'b-box': {
                    //组件的模板
                    template: `
                    <div>
                    //使用template选项,定义组件的模板,注意:模板中必须包含一个根标签
                        <div class='list' v-for="(item,index) in list">
                                <h2 >{{item.title}}</h2>
                                <p >{{item.content}}</p>
                         </div>
                     </div>
                   `,
                 //定义组件的属性,注意:必须要用''
                    props: ['list']
                }

            },
            // 注意:Vue实例的data选项可以是一个对象,也可以是一个方法,由该方法返回一个对象
            // 但是在组件中,data选项必须是一个方法,由该方法返回一个对象
            // 因为组件可能会使用很多次,如果data选项是对象的话,会导致多个组件使用了同一份数据。
            data() {
                return {
                    list: [{
                        title: '奔驰',
                        content: '梅赛德斯-奔驰(Mercedes-Benz)是世界闻名的豪华汽车品      牌。1886年1月,卡尔·本茨发明了世界上第一辆三轮汽车,获得专利(专利号:DRP 37435 [1] ),被誉为“汽车的发明者”。'
                    },

                    {
                        title: '宝马',
                        content: '宝马(BMW),中文全称为巴伐利亚发动机制造厂股份有限公司,德国汽车品牌,宝马的车系有i、X、Z、纯数字4个车型,1、2、3、4、5、6、7、8等几个系列,还有在各系基础上进行改进的M系(宝马官方的高性能改装部门',
                    },
                    {
                        title: '奥迪',
                        content: '德国豪华汽车品牌,其标志为四个圆环相扣。现为德国大众汽车公司的子公司。2018年12月20日,2018世界品牌500强排行榜发布,奥迪位列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选项,用于定义组件的属性,有两种方式:1.定义数组,2.定义对象
               //注意:props是只读的,不能修改所以需要在data里重新定义一个值用来接收
               //用于父组件给子组件传递数据
            // 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插槽
插槽的主要作用是帮助我们更好的在其他组件中进行布局。当想要便携可重用的控件时尤为重要。

适用场景:
在自定义编写组件时,多个组件里面的内容不完全相同时,如果疯狂使用v-show或者v-if来控制不同的组件展示不同的内容会有些许的麻烦,插槽就相当于是在父组件页面中的子组件标签里面编写一段代码,然后这段代码会被插入到子组件里面,但是子组件本身是有dom元素的,所以插入的时候需要根据slot标签的位置来决定插入的位置,又或者是根据slot的名称来确定。

<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>全国著名小吃</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:'长沙',
                        content:'长沙的臭豆腐真好吃'
                    }
                ]
            }
        })
    </script>

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容