组件、父子间的通信
2018-01-08 本文已影响3人
xlayzheng
- 自定义的控件(自定义的标签),能够封装可重用的代码,可扩展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