>可重復復用的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
}
})
```