【老司机带你飞】vue.js基础入门教程(十一)
组件
组件(Component)是vue.js" title="vue.js">vue.js最强大的功能之一。
组件可以扩展HTML元素,封装可重用的代码。
组件系统让我们可以用独立可复用的小组件来构建大型应用。
组件在vue脚手架开发中扮演着很重要的角色。
1) 注册全局组件
<div id="app"> <button-counter></button-counter>
</div>
<script>
Vue.component('button-counter',{
data:function(){
return {
count:0
}
},
template:"<button v-on:click='count++'>你敲击了{{count}}次</button>"
});
var app = new Vue({
el:"#app"
})
</script>
注意:
a. 组件的注册应该写在vue实例之前
b. Vue.component()中传入的第一个值是组件名称,第二个值是一个对象,是组件的选项参数
c. data选项必须是一个函数,目的是组件复用时组件数据的相互独立
d. 组件名称不要和原有的html标签名称相同,会产生冲突
e. 组件名称使用“component-name”和“componentName”(小驼峰)时,模板中调用组件都要写为:<component-name></component-name>
2)通过props选项,向子组件传递数据
<div id="app"> <blog-post title="博客标题"></blog-post>
</div>
<script>
Vue.component('blog-post',{
props:["title"],
template:"<h1>{{title}}</h1>"
});
var app = new Vue({
el:"#app"
})
</script>
在实际开发当中,data中可能存在多组博文数据,我们可以这样操作
<div id="app"> <blog-post v-for="blog in blogs" v-bind:key="blog.id" v-bind:title="blog.title"></blog-post>
</div>
<script>
Vue.component('blog-post',{
props:["title"],
template:"<h1>{{title}}</h1>"
});
var app = new Vue({
el:"#app",
data:{
blogs:[
{id:1,title:"标题1"},
{id:2,title:"标题2"},
{id:3,title:"标题3"},
{id:4,title:"标题4"}
]
}
})
</script>
3)单个根元素
一般一个组件模板中都不止一个包含一个标签,此时我们需要把多个标签包含在一个根元素中,不然只会显示第一个元素内容。
<div id="app"> <blog-post v-for="blog in blogs" v-bind:key="blog.id" v-bind:title="blog.title" v-bind:content="blog.content"></blog-post>
</div>
<script>
Vue.component('blog-post',{
props:["title","content"],
template:"<div>" +
"<h1>{{title}}</h1>" +
"<p>{{content}}</p>" +
"</div>"
});
var app = new Vue({
el:"#app",
data:{
blogs:[
{id:1,title:"标题1",content:"博文1"},
{id:2,title:"标题2",content:"博文2"},
{id:3,title:"标题3",content:"博文3"},
{id:4,title:"标题4",content:"博文4"}
]
}
})
</script>
如果博客数据中包含多个字段,我们可以考虑把整个的博客数据传入组件
<div id="app"> <blog-post v-for="blog in blogs" v-bind:key="blog.id" v-bind:blog="blog"></blog-post>
</div>
<script>
Vue.component('blog-post',{
props:["blog"],
template:"<div>" +
"<h1>{{blog.title}}</h1>" +
"<p>{{blog.content}}</p>" +
"<p>{{blog.time}}</p>" +
"<p>{{blog.comment}}</p>" +
"</div>"
});
var app = new Vue({
el:"#app",
data:{
blogs:[
{id:1,title:"标题1",content:"博文1",time:"今天",comment:"评论1"},
{id:2,title:"标题2",content:"博文2",time:"今天",comment:"评论2"},
{id:3,title:"标题3",content:"博文3",time:"今天",comment:"评论3"},
{id:4,title:"标题4",content:"博文4",time:"今天",comment:"评论4"}
]
}
})
</script>
4)监听子组件事件
<div id="app"> <div v-bind:style="{fontSize:fontSize+'em'}">
<blog-post v-for="blog in blogs" v-bind:key="blog.id" v-bind:blog="blog" v-on:enlarge-text="fontSize+=0.1"></blog-post>
</div>
</div>
<script>
Vue.component('blog-post',{
props:["blog"],
template:"<div>" +
"<button v-on:click='$emit(\"enlarge-text\")'>放大字体</button>" +
"<h1>{{blog.title}}</h1>" +
"<p>{{blog.content}}</p>" +
"<p>{{blog.time}}</p>" +
"<p>{{blog.comment}}</p>" +
"</div>"
});
var app = new Vue({
el:"#app",
data:{
blogs:[
{id:1,title:"标题1",content:"博文1",time:"今天",comment:"评论1"},
{id:2,title:"标题2",content:"博文2",time:"今天",comment:"评论2"},
{id:3,title:"标题3",content:"博文3",time:"今天",comment:"评论3"},
{id:4,title:"标题4",content:"博文4",time:"今天",comment:"评论4"}
],
fontSize:1
}
})
</script>
a. 组件调用处绑定自定义事件
b. 组件模板内部绑定正常的vue事件,如:v-on:click,执行组件调用处的自定义事件,以此达到父组件监听子组件事件的目的
v-on:click可以放置一个方法名,在methods方法中使用$emit执行组件调用处的自定义事件
Vue.component('blog-post',{ props:["blog"],
template:"<div>" +
"<button v-on:click='enlargeText'>放大字体</button>" +
"<h1>{{blog.title}}</h1>" +
"<p>{{blog.content}}</p>" +
"<p>{{blog.time}}</p>" +
"<p>{{blog.comment}}</p>" +
"</div>",
methods:{
enlargeText:function () {
this.$emit('enlarge-text');
}
}
});
5)动态组件
在不同组件之间进行动态切换是非常有用的,如选项卡的操作,可以通过页面标签<component>
绑定is属性来实现
<style> .tab-button{
border: 0;
outline: none;
}
.active{
background: #999;
color: #ffffff;
}
#app div{
height: 200px;
border: 1px solid #cccccc;
}
</style>
<div id="app">
<button v-for="tab in tabs" v-bind:class="['tab-button',{active:currentTab===tab.menuCode}]" v-on:click="currentTab=tab.menuCode">{{tab.menuName}}</button>
<component v-bind:is="currentTabComponent"></component>
</div>
<script>
Vue.component('tab-home',{
template:'<div>首页组件</div>'
});
Vue.component('tab-about',{
template:'<div>关于我们组件</div>'
});
Vue.component('tab-contact',{
template:'<div>联系我们组件</div>'
});
var app = new Vue({
el:"#app",
data:{
currentTab:'home',
tabs:[
{
menuCode:'home',
menuName:'首页'
},
{
menuCode:'about',
menuName:'关于我们'
},
{
menuCode:'contact',
menuName:'联系我们'
}
]
},
computed:{
currentTabComponent:function () {
return 'tab-'+this.currentTab;
}
}
})
</script>
最终实现:
6)在动态组件上使用keep-alive
将动态组件放入到keep-alive标签中,可以使组件中切换状态保持住
<style> .tab-button{
border: 0;
outline: none;
}
.active{
background: #999;
color: #ffffff;
}
#app div{
height: 200px;
border: 1px solid #cccccc;
}
.navli{
list-style: none;
cursor: pointer;
}
.navactive{
background: #999999;
color: #ffffff;
}
.nav-ul{
width:20%;
float: left;
}
.navComponent{
width: 70%;
float: left;
}
</style>
<div id="app">
<button v-for="tab in tabs" v-bind:class="['tab-button',{active:currentTab===tab.menuCode}]" v-on:click="currentTab=tab.menuCode">{{tab.menuName}}</button>
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>
</div>
<script>
Vue.component('tab-home',{
data:function(){
return {
currentNav:"nav1",
navs:[
{
navCode:"nav1",
navName:"导航1"
},
{
navCode:"nav2",
navName:"导航2"
},
{
navCode:"nav3",
navName:"导航3"
}
]
}
},
template:'<div>' +
'<ul class="nav-ul">' +
'<li v-for="nav in navs" v-bind:class="[\'navli\',{navactive:currentNav===nav.navCode}]" v-on:click="currentNav=nav.navCode">{{nav.navName}}</li>' +
'</ul>' +
'<component v-bind:is="currentNavComponent" class="navComponent"></component>'+
'</div>',
computed: {
currentNavComponent: function () {
return this.currentNav;
}
}
});
Vue.component('nav1',{
template:'<div>导航1内容</div>'
});
Vue.component('nav2',{
template:'<div>导航2内容</div>'
});
Vue.component('nav3',{
template:'<div>导航3内容</div>'
});
Vue.component('tab-about',{
template:'<div>关于我们组件</div>'
});
Vue.component('tab-contact',{
template:'<div>联系我们组件</div>'
});
var app = new Vue({
el:"#app",
data:{
currentTab:'home',
tabs:[
{
menuCode:'home',
menuName:'首页'
},
{
menuCode:'about',
menuName:'关于我们'
},
{
menuCode:'contact',
menuName:'联系我们'
}
]
},
computed:{
currentTabComponent:function () {
return 'tab-'+this.currentTab;
}
}
})
</script>
7)注册局部组件
全局组件很容易产生不被用到的组件资源浪费,此时会用到局部组件注册(在脚手架环境下体现更明显)
<div id="app"> <component-a></component-a>
<component-b></component-b>
</div>
<script>
var componentA = {
template:"<h1>局部组件A</h1>"
}
var componentB = {
template:"<h1>局部组件B</h1>"
}
var app = new Vue({
el:"#app",
components:{
'component-a':componentA,
'component-b':componentB
}
})
</script>
——易动学院毕老师
QQ:732005030
扫码加微信
以上是 【老司机带你飞】vue.js基础入门教程(十一) 的全部内容, 来源链接: utcz.com/z/375385.html