组件基础
简单示例
<body>
<div id="components-demo">
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
</body>
<script src="https://cdn.bootcss.com/vue/2.2.2/vue.min.js"></script>
<script>
//定义一个名为button-counter的新组件
Vue.component("button-counter",{
data:function(){
return {
count:0
}
},
template:'<button v-on:click="count++">You click me {{count}} times</buttom>'
});
new Vue({
el:"#components-demo"
});
</script>
注意:data 必须是一个函数
组件的组织
通常一个应用会以一棵树嵌套的组件树的形式来组织。
例如,页头,侧边栏、内容区等组件,每个组件又包含了其他的像导航链接、博文之类的组件。
这些组件必须先注册以便Vue能够识别。两种组件的注册类型:全局注册,局部注册。
全局注册是通过 Vue.component 实现的。
Vue.component("my-component-name",{
//...options...
})
全局注册的组件可以用在被其注册后的任何(new Vue)新创建的Vue根实例,也包括其组件树中的所有子组件的模板中。
通过Prop向子组件传递参数
Vue.component('blog-post',{
props:['title'],
template:"<h3>{{title}}</h3>"
});
new Vue({
el:"#blog-post-demo",
data:{
posts:[
{id:1,title:"MY"},
{id:2,title:"your"},
{id:3,title:"their"}
]
}
});
<div id="blog-post-demo">
<blog-post v-for="post in posts" v-bind:key="post.id" v-bind:title="post.title"></blog-post>
</div>
使用 v-bind 动态传递prop.
单个根元素
当构建一个<blog-post>组件时,里面包含的东西不止一个标题,应还有正文。且每个组件必须只有一个根元素。可以将模板的内容包裹在一个父元素内。
<div class="blog-post">
<h3>{{title}}</h3>
<div v-html="content"></div>
</div>
但是当组件变得复杂的时候,如果为每一个相关的信息定义一个prop会变得很麻烦。应该重构这个组件,让它变成接受一个单独的post prop:
<blog-post v-for="post in posts" v-bind:key="post.id" v-bind:post="post"></blog-post>
Vue.component('blog-post',{
prop:['post],
template:
<div class="blog-post">
<h3>{{post.title}}</h3>
<div v-html="post.content"></div>
</div>
})
监听子组件事件
如果博文中要引入一个辅助功能来放大博文的字号,同时让页面其他部分保持默认字号,可以通过在其父组件中添加一个postFontSize数据属性来支持这个功能。
<div id="blog-posts-events-demo">
<div :style="{fontSize:postFontSize + 'em'}">
<blog-post v-on:enlarge-text="postFontSize += 0.1" v-for="post in posts" v-bind:key="post.id" v-bind:post="post"></blog-post>
</div>
</div>
Vue.component('blog-post',{
props:['post'],
template:
<div class="blog-post">
<h3>{{post.title}}</h3>
<button>
Enlarge
</button>
<div v-html="post.content"></div>
</div>
});
new Vue({
el:"#blog-posts-events-demo",
data:{
posts:[/* ... */],
postFontSize:1
}
});
通过插槽发布内容
Vue.component("alert-box",{
template:
<div class="demo-alert-box">
<strong>Error!</strong>
<slot></slot>
</div>
})
动态组件
<component v-bind:is="currentTabComponent"></component>
解析DOM模板时的注意事项
<table>
<blog-post-row></blog-post-row>
</table>