1、组件的概念
组件是Vue中一个非常重要的概念,相当的重要,每个组件实现特定的功能。
组件可以看作是可复用的Vue实例。
2、组件的注册
在Vue中,组件分为全局组件和局部组件,和filter过滤器一样。
全局组件作用于全局
局部组件作用于局部,具体的来说是在该vue实例下的div中使用
2.1、全局组件的注册
在Vue中使用Vue.component('组件名称','{组件对象}')来创建组件,在html中使用组件名称的标签来使用它。
<div id="app" >
<com1></com1> //定义的组件名称使用
</div>
<script>
Vue.component('com1',{
template:'<h3>这是组件</h3>' //这里使用了template来创建想要的html模板
});
var vm=new Vue({
el:'#app',
data:{
msg:" "
},
methods:{
showParent:function () {
console.log("这是父组件的方法");
}
},
components:{
}
})
</script>
运行结果:
打开调试工具
组件中的template中的html模板渲染到了div中。
Vue.component('组件名称',组件对象),其中这个组件对象我们可以单独创建出来。
var login={
template:'<h3>这是组件</h3>'
};
Vue.component('com1',login);
但是在html模板中使用的依旧是<com1></com1>。
我们还可以通过Vue.extend来注册一个组件。
var login=Vue.extend({
template:'<h3>这是组件</h3>'
});
Vue.component('com1',login);
2.2、私有组件的注册
私有组件的注册是在Vue实例中进行注册的,使用的是Vue实例中的属性,components,同样的在html模板中使用组件名称的html标签来使用
components:{
组件名称:{
template:....
}
}
<div id="app" >
<com1></com1>
</div>
<script>
var vm=new Vue({
el:'#app',
data:{
msg:" "
},
methods:{
showParent:function () {
console.log("这是父组件的方法");
}
},
components:{
com1:{ //注册的组件名称为com1
template:'<h3>这是一个组件</h3>'
}
}
})
</script>
运行截图:
2.3 <template>创建
无论是在私有组件还是全局组件中,我们在template:" "中定义要使用的html模板,但是在这里面定义的html标签没有高亮没有提示,而且显得代码混乱。
我们可以在html中使用<template id='id'>标签来解决这个问题。
<div id="app" >
<com1></com1>
</div>
<!--创建template标签存放自己的html内容-->
<template id="combyid">
<h3>这是一个使用template生成的组件</h3>
</template>
<script>
var comObj={
template:'#combyid' //这里的template传入的不再是HTML模板而是一个id
};
Vue.component('com1',comObj);
运行截图
无论是在<template>中编写html,还是在comObj中的template中,只能存在一个根元素,否则会报错!!!
3、组件的属性
作为vue中的重要特性,必备许多必不可少的属性。
3.1、data
组件是可复用的Vue实例,组件中也存在data,但是data必须是一个函数,且显式的返回一个对象,这个对象中的data和Vue实例中的data一样使用输出。
<div id="app" >
<com1></com1>
</div>
<template id="combyid">
<h3>组件中的数据是++++{{msg}}</h3> <!--data中的数据像Vue实例一样使用-->
</template>
<script>
var comObj={
template:'#combyid',
data:function () { //data必须是一个function 且要有return一个对象
return{
msg:'组件的data'
}
}
};
Vue.component('com1',comObj);
var vm=new Vue({
el:'#app',
data:{
msg:" "
},
methods:{
showParent:function () {
console.log("这是父组件的方法");
}
},
components:{
}
})
</script>
运行结果
3.2、methods
组件中也存在着methods对象,存放着仅供组件使用的方法。
<div id="app" >
<com1></com1>
</div>
<template id="combyid">
<div>
<h3>组件中的数据是++++{{msg}}</h3>
<!--@click简历一个点击事件触发show方法-->
<input type="button" value="点击使用show方法" @click="show">
</div>
</template>
<script>
var comObj={
template:'#combyid',
data:function () {
return{
msg:'组件的data'
}
},
methods:{ //存放方法
show:function () {
console.log("show被调用");
}
}
};
Vue.component('com1',comObj);
var vm=new Vue({
el:'#app',
data:{
msg:" "
},
methods:{
showParent:function () {
console.log("这是父组件的方法");
}
},
components:{
}
})
</script>
运行结果:
3.3、props
当我们需要从父组件(Vue实例)获取数据时,就需要props。
-
在组件的html引用中添加,v-bind:自定义名称='父组件数据'
-
在组件对象中的props,注册这一个自定义名称
<div id="app" >
<!--组件的html引用中,需要添加v-bind:自定义名称="父组件数据"-->
<com1 v-bind:parentmsg="msg"></com1>
</div>
<template id="combyid">
<div>
<h3>组件中的数据是++++{{parentmsg}}</h3>
</div>
</template>
<script>
var comObj={
template:'#combyid',
data:function () {
return{
msg:'组件的data'
}
},
methods:{ //存放方法
show:function () {
console.log("show被调用");
console.log(this);
}
},
//props中需要创建自定义数据名称
//类似一个包装效果
props:['parentmsg']
};
Vue.component('com1',comObj);
var vm=new Vue({
el:'#app',
data:{
msg:"父组件"
},
methods:{
showParent:function () {
console.log("这是父组件的方法");
}
},
components:{
}
})
</script>
运行结果:
当我们父组件中的数据为一个数组或者对象呢?
数组:
<div id="app" >
<!--组件的html引用中,需要添加v-bind:自定义名称="父组件数据"-->
<com1 v-bind:parentmsg="msg"></com1>
</div>
<template id="combyid">
<div>
<h3 v-for="(item,key) in parentmsg">组件中的数据是++++{{item}}</h3>
</div>
</template>
<script>
var comObj={
template:'#combyid',
data:function () {
return{
msg:'组件的data'
}
},
methods:{ //存放方法
show:function () {
console.log("show被调用");
console.log(this);
}
},
//props中需要创建自定义数据名称
//类似一个包装效果
props:['parentmsg']
};
Vue.component('com1',comObj);
var vm=new Vue({
el:'#app',
data:{
msg:['父组件','get',10]
},
methods:{
showParent:function () {
console.log("这是父组件的方法");
}
},
components:{
}
})
</script>
运行结果:
对象:
<div id="app" >
<!--组件的html引用中,需要添加v-bind:自定义名称="父组件数据"-->
<com1 v-bind:parentmsg="msg"></com1>
</div>
<template id="combyid">
<div>
<h3 v-for="(item,key) in parentmsg">组件中的数据是++++{{key}}:{{item}}</h3>
</div>
</template>
<script>
var comObj={
template:'#combyid',
data:function () {
return{
msg:'组件的data'
}
},
methods:{ //存放方法
show:function () {
console.log("show被调用");
console.log(this);
}
},
//props中需要创建自定义数据名称
//类似一个包装效果
props:['parentmsg']
};
Vue.component('com1',comObj);
var vm=new Vue({
el:'#app',
data:{
msg:{
name:'父组件',
type:'get',
value:10}
},
methods:{
showParent:function () {
console.log("这是父组件的方法");
}
},
components:{
}
})
</script>
运行结果:
props最重要的作用是,子组件能够接收到父组件的数据!!!当父组件中的数据是引用类型的话,子组件更改props中的数据,父组件中的数据也会一并更改!!!如果是基本类型的话会报错
<div id="app" >
<!--组件的html引用中,需要添加v-bind:自定义名称="父组件数据"-->
<com1 v-bind:parentmsg="msg"></com1>
</div>
<template id="combyid">
<div>
<h3 v-for="(item,key) in parentmsg">组件中的数据是++++{{key}}:{{item}}</h3>
<input value="点击改变父组件的msg" @click="change" type="button">
</div>
</template>
<script>
var comObj={
template:'#combyid',
data:function () {
return{
msg:'组件的data'
}
},
methods:{ //存放方法
show:function () {
console.log("show被调用");
console.log(this);
},
change:function () {
this.parentmsg.value=50;
}
},
//props中需要创建自定义数据名称
//类似一个包装效果
props:['parentmsg']
};
Vue.component('com1',comObj);
var vm=new Vue({
el:'#app',
data:{
msg:{
name:'父组件',
type:'get',
value:10}
},
methods:{
showParent:function () {
console.log("这是父组件的方法");
}
},
components:{
}
})
</script>
运行结果:
4、组件间的通信
4.1、父组件传递数据到子组件
父组件的数据是通过props传递到子组件的,通过props可以使用父组件的数据。具体例子可看props。
父组件不止数据,方法都能被子组件使用。具体的做法是
-
在组件的html引用中添加v-on:自定义方法="父组件中的方法"
-
在组件对象中创建一个方法,这个方法包含了自定义方法的使用
-
在组件对象创建的方法中添加"this.$emit('自定义方法')"
-
在组件中可以使用这个创建的方法,达到使用父组件方法的目的
<div id="app" >
<!--组件的html引用中,需要添加v-on:自定义事件="父组件事件名称"-->
<com1 v-bind:parentmsg="msg" v-on:myclick="showParent"></com1>
</div>
<template id="combyid">
<div>
<h3>组件中的数据是++++</h3>
<input value="点击使用父组件方法" @click="show" type="button">
</div>
</template>
<script>
var comObj={
template:'#combyid',
data:function () {
return{
}
},
methods:{
show:function () { //定义一个函数,里面包含着自定义事件的使用
this.$emit('myclick'); //使用this.$emit('自定义事件')
}
},
};
Vue.component('com1',comObj);
var vm=new Vue({
el:'#app',
data:{
msg:{
name:'父组件',
type:'get',
value:10}
},
methods:{
showParent:function () {
console.log("这是父组件的方法");
}
},
components:{
}
})
</script>
运行结果:
4.2、子组件传递数据给父组件
子组件通过自定义的方法将数据传递给父组件
具体的思想是:子组件能够使用父组件的方法,那么就通过向此方法传递参数来达到传递数据给父组件的目的
<div id="app" >
<!--组件的html引用中,需要添加v-on:自定义事件="父组件事件名称"-->
<com1 v-bind:parentmsg="msg" v-on:myclick="showParent"></com1>
</div>
<template id="combyid">
<div>
<h3>组件中的数据是++++</h3>
<input value="点击使用父组件方法" @click="show" type="button">
</div>
</template>
<script>
var comObj={
template:'#combyid',
data:function () {
return{
msg:'子组件的数据'
}
},
methods:{
show:function () { //定义一个函数,里面包含着自定义事件的使用
this.$emit('myclick',this.msg); //使用this.$emit('自定义事件',参数)传递数据到父组件中
}
},
};
Vue.component('com1',comObj);
var vm=new Vue({
el:'#app',
data:{
dataSon:null
},
methods:{
showParent:function (item) {
console.log("这是父组件的方法");
this.dataSon=item;
console.log(this.dataSon)
}
},
components:{
}
})
</script>
运行结果: