組件基礎
// 定義一個名爲 button-counter 的新組件
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
組件是可複用的 Vue 實例,且帶有一個名字。我們可以在一個通過 new Vue 創建的 Vue 根實例中,把這個組件作爲自定義元素來使用:
<div id="components-demo">
<button-counter></button-counter>
</div>
new Vue({ el: '#components-demo' })
因爲組件是可複用的 Vue 實例,所以它們與 new Vue 接收相同的選項,例如 data、computed、watch、methods 以及生命週期鉤子等。僅有的例外是像 el 這樣根實例特有的選項
使用組件的細節點
1.組件中使用is解決標籤規範
例子:
<div id="app">
<table>
<tbody>
<row></row>
<row></row>
<row></row>
</tbody>
</table>
</div>
<script>
Vue.component('row', {
template: '<tr><td>this is a row</td></tr>'
})
var vm = new Vue({
el: '#app'
})
</script>
打開瀏覽器:出現三行row 顯示似乎沒有問題,可以當我們查看查看器時
發現三行rows顯示在了table外面!這是因爲html5的規範裏tbody裏面必須放的是tr,而我們放的是row,所以它是不能正常解析的。這時候我們可以使用Vue提供的is來解決類似問題i,我們把代碼修改爲:
<table>
<tbody>
<tr is='row'></tr>
<tr is='row'></tr>
<tr is='row'></tr>
</tbody>
</table>
類似的ol,ul都可以使用is來解決標籤規範造成的bug。
2.非根組件中data必須是函數
繼續上面的例子我們把代碼修改爲
Vue.component('row', {
data: {
content: 'this is a row'
}
template: '<tr><td>{{content}}</td></tr>'
})
這樣是會報錯的,如果是一個根組件,用上面的方法是沒問題的,可當我們在非根組件的子組件中定義data時,data必須是function而不是對象,而且這個函數需要返回一個對象,對象裏包含你的數據。
Vue.component('row', {
data: function () {
return {
content: 'this is a content'
}
},
template: '<tr><td>{{content}}</td></tr>'
})
這麼設計是因爲,一個子組件不像根組件,只會被調用一次,它可能被調用很多次,我們希望每一個子組件不和其它子組件數據相沖突,每個子組件不互相影響。
3.操作dom
Vue是不建議我們在代碼中操作dom的,可是有時候在處理一些複雜的動畫效果時候,有時候我們還真需要操作dom。
ref
我們可以通過像標籤添加ref屬性的方法獲取dom節點,通過this.$refs.xxx取得該dom節點
<div id="root">
<div
ref='hello'
@click='handleClick'
>
hello world
</div>
</div>
<script type="text/javascript">
var vm =new Vue({
el: '#root',
methods: {
handleClick: function ( ) {
console.log(this.$refs.hello);
}
}
})
</script>
我們點擊後查看控制檯,可以看到得到了這個div
那麼組件中使用ref屬性的情況呢?
<div id="root1">
<counter
@change="handleChange"
ref="one"
></counter>
<counter
@change="handleChange"
ref="two"
></counter>
<div>
{{total}}
</div>
</div>
<script type="text/javascript">
Vue.component('counter',{
template: "<div @click='handleClick'>{{number}}</div>",
data () {
return {
number: 0
}
},
methods: {
handleClick: function () {
this.number++;
this.$emit('change')
}
}
})
var vm =new Vue({
el: '#root1',
data: {
total:''
},
methods: {
handleChange: function ( ) {
this.total=this.$refs.one.number+this.$refs.two.number
}
}
})
</script>
通過運行這段代碼,可以看出this.$refs.xxx取得的是子組件的引用。