美文网首页Vue
组件、父子间的通信

组件、父子间的通信

作者: xlayzheng | 来源:发表于2018-01-08 16:29 被阅读3次
    • 自定义的控件(自定义的标签),能够封装可重用的代码,可扩展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

    相关文章

      网友评论

        本文标题:组件、父子间的通信

        本文链接:https://www.haomeiwen.com/subject/uqmbnxtx.html