>可重复复用的Vue实例
组件的定义
`Vue.component("componet_name",{})`
`Vue.component("componet_name",{template:"html模版片段"})`
```
// 定义一个名为 button-counter 的新组件
//注意传值给组件data不是一个对象而是一个函数
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
```
使用自定义的这个组件
~~~
<div id="app">
<button-counter></button-counter>
<button-counter></button-counter>
</div>
<script type="text/javascript">
new Vue({ el: '#app' })
</script>
~~~
## **通过 Prop 向子组件传递数据**
我们 新建的button-counter组件也需要src class 等属性而且需要传入到模版内部,可通过props添加组件属性
```
Vue.component('button-counter', {
props:["title","name","description"],
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++"> {{description}} You clicked me {{ count }} times.</button>'
})
```
使用:
```
<div id="app">
<button-counter description="哈哈"></button-counter>
<button-counter description="嘻嘻"></button-counter>
</div>
<script type="text/javascript">
new Vue({ el: '#app' })
</script>
```
注意定义模版是模版的父级只能是存在一个元素子级随便
```
错误方法
template: '<h1>hello</h1> <button v-on:click="count++"> {{description}} You clicked me {{ count }} times.</button>'
正确方法
template: '<div> <h1>hello</h1> <button v-on:click="count++"> {{description}} You clicked me {{ count }} times.</button></div>'
```
可以使用[vm.$emit](https://cn.vuejs.org/v2/api/#vm-emit)触发当前实例上的事件
组件上直接使用v-on是无效的,下面这个doThis函数毫无反应
```
<body>
<div id="app">
<button-counter description="哈哈" v-on:click="doThis">asd</button-counter>
</div>
<script type="text/javascript">
Vue.component('button-counter', {
props:["title","name","description"],
data: function () {
return {
count: 0
}
},
template: '<div> <h1>hello</h1> <button v-on:click="count++"> {{description}} You clicked me {{ count }} times.</button></div>'
})
new Vue({
el:"#app",
methods:{
doThis:function(){
alert(1111);
}
}
});
</script>
</body>
```
这时我们需要在组件内部通过$emit来触发doThis这个事件函数
`this.$emit("do_this",this.count)`用来触发do_this事件,注意HTML属性是大小写不敏感的这里的事件名会强制转换成小写,如果定义有大写字母,则会报错
```
<body>
<div id="app">
<button-counter description="哈哈" v-on:do_this="doThis">asd</button-counter>
</div>
<script type="text/javascript">
Vue.component('button-counter', {
props:["title","name","description"],
data: function () {
return {
count: 0
}
},
template: '<div> <h1>hello</h1> <button v-on:click="clickFun"> {{description}} You clicked me {{ count }} times.</button></div>',
methods:{
clickFun:function(){
this.count++;
//触发组件外部事件的关键
//第一个参数是组件定义的外部事件名,第二个到N个是事件函数的参数
this.$emit("do_this",this.count)
}
}
})
new Vue({
el:"#app",
methods:{
doThis:function(count){
alert(count);
}
}
});
</script>
</body>
```
## **通过插槽分发内容**
注意到组件中的内容asd没有显示我们怎么在组件中添加内容然后插入到模版中呢?使用`<slot>`
```
<body>
<div id="app">
<button-counter description="哈哈" v-on:do_this="doThis">asd</button-counter>
</div>
<script type="text/javascript">
Vue.component('button-counter', {
props:["title","name","description"],
data: function () {
return {
count: 0
}
},
template: '<div> <h1>hello</h1><slot></slot> <button v-on:click="clickFun"> {{description}} You clicked me {{ count }} times.</button></div>',
methods:{
clickFun:function(){
this.count++;
//触发组件外部事件的关键
this.$emit("do_this",this.count)
}
}
})
new Vue({
el:"#app",
methods:{
doThis:function(count){
alert(count);
}
}
});
</script>
</body>
```
上面是全局注册
## **局部注册**
```
//局部注册 在new Vue对象的时候申明一个components
new Vue({
el:"#app",
methods:{
doThis:function(count){
alert(count);
}
},
components:{
"button-counter":{
template:"<button>按钮</button>"
}
}
});
使用
<button-counter></button-counter>
```
也可以这样
```
var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }
```
然后在`components`选项中定义你想要使用的组件
```
new Vue({
el: '#app',
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
```