组件、父子间的通信

  • 自定义的控件(自定义的标签),能够封装可重用的代码,可扩展HTML标签功能

全局组件 不同作用域内均可使用

  • 定义方式:
方式一:
Vue.component('name',{
    template:'html结构'     // 这个html结构只能有一个根元素
    或者 
    template:'#search'    
})
方式二:
        <!--
            定义模板    在容器外定义
            为template添加id
            设置template:'selector'
        -->
------------------------------------------------------------------------------------------------
        <template id="search">
            <!--模板中添加事件-->
            <div>
                <input type="text"/>
                <input type="button" value="百度一下" @click="fn()"/>  //方法加在组件中
                <p>{{msg+','+name}}</p>
            </div>
        </template>
------------------// script中的实例外面定义组件----------------------------------------
   Vue.component('testcomponent',{
        template:'#search',                //关联上面的组件
        data:function(){                     // 注意!!!模板配置项中的data是方法!!!
            return{                          //!!!模板中的数据用return返回!!!
                msg:'hello',
                name:'lily'
            }
        },
        methods:{
            fn:function(){
                console.log(11111)
            }
        }
    })
  • 上面的全局组件写法就是:
    Vue.component('组件名',{构造器})
  • 我们还可以分开来写:
//1.创建构造器
let 构造器名 = Vue.extend({
        template:   ... ,
         ......
    })

//2.注册组件
Vue.component('组件名' , 构造器名)

局部组件 只能在定义该组件的作用域内使用

  • 定义方式:
    <body>
        <div id="box">
---------------------调用组件------------------------
             <testcomponent></testcomponent>
             <testcomponent2></testcomponent2>
             <my-test></my-test>
        </div>
----------------------定义组件------------------------
        <template id="search">
            <div>
                <input type="text"/>
                <input type="button" value="百度一下" @click="fn()"/>
                <p>{{msg+','+name}}</p>
            </div>
        </template>
    </body>
-----------------直接在实例中添加components配置项----------
    var vm = new Vue({
        el:'#box',
        data:{},
        components:{                     //添加组件配置项
            'testcomponent':{          
                template:'#search',
                data:function(){
                    return{
                        msg:'hey',
                        name:'monica'
                    }
                },
                methods:{
                    fn:function(){
                        alert(250)
                    }
                }
            },
            'testcomponent2':{
                template:'<p>第二个局部组件</p>'
            },
            //如果定义组件时用了驼峰命名法,在调用时用  - 链接
            'myTest':{
                template:'<p>***************myTest************</p>'
            }, 
            //每一个组件相当于一个vue实例
            //所以组件之间的作用域是完全独立的,组件之间的值是不能够共用的
        }
        
    });

!!! 如果定义组件时用了驼峰命名法,在调用时用 - 链接

  • props选项
  • 作用:props选项用来声明它期待获得的数据
  • 本质:元素的属性
  • 书写位置:组件内部,与template等配置同级
  • 使用:
    • 1.与data一样,props可以使用在模板中
    • 2.可以像在vm实例中像this.message这样使用props定义的值
  • 语法:
---------------------js中定义props-----------------------
props:[ 'message1' , 'message2' , 'message3' , 'message4' ...... ]

---------------------html中,传入值-----------------------
<组件 message1='val'> </组件>



image.png

代码实现:

    <body>
        <div id="box">
              <my-head txt='书影音' src1='img/search1.png'  src2='img/chat1.png'></my-head>
              <my-head txt='广播'  src1='img/team1.png'    src2='img/chat1.png'></my-head>
              <my-head txt='小组'  src1='img/search1.png'  src2='img/chat1.png'></my-head>
              <my-head txt='我的'  src2='img/setting1.png'></my-head>
        </div>
        
        <template id="head">
            <div class="headWrap">
                 <span>{{txt}}</span>
                 <img class="leftpic" :src="src1"/>   //冒号绑定属性
                 <img class="rightpic" :src="src2"/>
            </div>
        </template>
    </body>
  <script type="text/javascript">
    //创建vue实例
    var vm = new Vue({
        el:'#box',
        data:{},
        components:{                     //添加组件配置项
            'myHead':{          
                template:'#head',
                props:['txt','src1','src2'],  
            },
        }       
    });
</script>



  • slot槽口
  • 作用:在组件封装的过程中,向外部留出的一些槽口,也就是可供外部插入一些内容
  • 语法:<slot> </slot>
  • 不具名的槽口只能预留一个
  • 具名槽口
  • 具名槽口就是给槽口加一个name属性,在使用组件时插入的内容加上slot属性即可,插入内容的顺序按照模板中的顺序。且具名槽口可预留多个
        <div id="box">
              <my-head>
                 <span slot='slot2'>222</span> 
                 <p slot='slot1'>1111111111</p>  
              </my-head>

        </div>
        
        <template id="head">
            <div class="headWrap">
                 <span>这是组件内的内容</span>
                 <slot name='slot1'></slot>
                 <slot name='slot2'></slot>
            </div>
        </template>
--------------------------------------js------------------------------
    var vm = new Vue({
        el:'#box',
        data:{},
        components:{                     //添加组件配置项
            'myHead':{          
                template:'#head',
            },
        }    
    });
image.png

代码槽口实现:

        <div id="box">
              <my-head txt='书影音'>
                    <img class="leftpic" src="img/search1.png" slot='leftImg'/>  
                    <img class="rightpic" src="img/chat1.png" slot='rightImg'/>  
              </my-head>
              <my-head txt='广播'>
                    <img class="leftpic" src="img/team1.png" slot='leftImg'/>  
                    <img class="rightpic" src="img/chat1.png" slot='rightImg'/>  
              </my-head>
              <my-head txt='小组'>
                    <img class="leftpic" src="img/search1.png" slot='leftImg'/>  
                    <img class="rightpic" src="img/chat1.png" slot='rightImg'/>  
              </my-head> 
              <my-head txt='我的'>
                    <img class="rightpic" src="img/setting1.png" slot='rightImg'/>  
              </my-head>              
        </div>
        
        <template id="head">
            <div class="headWrap">
                 <span>{{txt}}</span>
                 <slot name='leftImg'></slot> 
                 <slot name='rightImg'></slot> 
            </div>
        </template>

------------------------------------js-------------------------------------
    var vm = new Vue({
        el:'#box',
        data:{},
        components:{                     //添加组件配置项
            'myHead':{          
                template:'#head',
                props:['txt']
            }
        }
    });
  • 父子组件
  • 组件中还可以再设置组件
components:{
        'parent':{
                  template:'父组件模板',
                  components:{
                         'child':{
                                  template:'子组件模板',
                                  ......
                          }
                  }
         }
}
  • 子组件要在其父组件的vue模板中调用
    <body>
        <div id="box">                        //定义视图容器
           <tab-bar> </tab-bar>               //组件调用
        </div>
        
        <template id="tabbar">
            <div class="tabbarWrap">
                <item txt='首页'>       //子组件要在其父组件中调用
                    <img slot='footer-icon' src="img/home.png" />
                </item>
                <item txt='书影音'>
                    <img slot='footer-icon' src="img/video.png" />
                </item>
                <item txt='广播'>
                    <img slot='footer-icon' src="img/bro.png" />
                </item>
                <item txt='小组'>
                    <img slot='footer-icon' src="img/teamm.png" />
                </item>
                <item txt='设置'>
                    <img slot='footer-icon' src="img/footsetting.png" />
                </item>
            </div>
        </template>
        
        <template id="item">
            <div class="itemWrap">
                <slot name='footer-icon'></slot>
                <span>{{txt}}</span>
            </div>
        </template>     
    </body>


-------------------------------js----------------------------
    var vm = new Vue({
        el:'#box',                            //关联视图容器
        data:{},
        components:{                           //添加组件配置项                               
            'tabBar':{                         //父组件
                template:'#tabbar',
                components:{                   //子组件  只能在父组件的模板中调用
                    'item':{
                        template:'#item',
                        props:['txt']
                     }
                 }
              },
          }     
    });
  • 注意!!!
    • 父子组件间作用域相互独立
    • 子组件只能在父组件的模板中进行调用
自定义事件、父子组件传值
  • 语法: 抛出自定义事件监听

    • this.$emit('event',val)
    • $emit ------ 实例方法,用来触发事件监听
    • event ----- 自定义事件名称
    • val ----- 通过自定义事件传递的值(可选参数)
  • 子传值给父 ----- 逆向传值 $emit

    • 事件触发接受原则:谁触发的监听,由谁接受
    • 子组件触发的监听,则由父模板中调用的子组件接受


      $emit.jpg
  • 父传值给子 ----- 正向传值 props

    props.jpg

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