美文网首页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