組件(components)是 Vue 的一種代碼復(fù)用機(jī)制缀去,components 把 JS 和 HTML 混合到一起芋膘,作為整個(gè) Vue 應(yīng)用層的基礎(chǔ)
這篇筆記的內(nèi)容僅涉及 Components,并不會(huì)涉及 Single File Components 這種 Vue SPA 開(kāi)發(fā)中的單文件組件啡莉,后者另做介紹
父組件和子組件
從 HTML 結(jié)構(gòu)上來(lái)看逃默,「父組件」是指頁(yè)面載入時(shí)候的 HTML模板 中的內(nèi)容攀圈,「父組件」會(huì)等待 「子組件」對(duì)其進(jìn)行相關(guān)的處理昭娩,「父組件」形如:
<div id="componentId">
<component-tag></component-tag>
</div>
「父組件」首先要進(jìn)行實(shí)例化凛篙,才能和「子組件」進(jìn)行交互,「父組件」的實(shí)例化過(guò)程形如:
new Vue({
el: '#componentId',
data: {
total: 0
},
methods: {
incrementTotal: function () {
this.total += 1
}
}
})
「子組件」在 HTML 上對(duì)「父組件」的指定標(biāo)簽(比如前面的 <component-tag> 標(biāo)簽)進(jìn)行替換栏渺,從而可以與「父組件」進(jìn)行交互呛梆,「子組件」的實(shí)例形如:
Vue.component('component-tag', {
template: '<button v-on:click="methodName">{{ counter }}</button>',
data: function () {
return {
counter: 0
}
},
methods: {
methodName: function () {
this.counter += 1
this.$emit('increment')
}
},
})
如果你僅僅希望「子組件」被所在的「父組件」使用,那么也可以直接將「子組件」寫(xiě)到父組件的實(shí)例過(guò)程中磕诊,這樣的「父子組件」形如:
new Vue({
el: '#componentId',
data: {
total: 0
},
methods: {
incrementTotal: function () {
this.total += 1
}
},
components: {
// <my-component> will only be available in parent's template
'my-component': {
template: '<div>A custom component!</div>'
}
}
})
「父組件」和「子組件」的交互過(guò)程填物,是通過(guò)「父組件」的 props 屬性,子組件的自定義事件來(lái)完成的霎终,這塊的官方文檔比較清晰:
In Vue.js, the parent-child component relationship can be summarized as props down, events up. The parent passes data down to the child via props, and the child sends messages to the parent via events. Let’s see how they work next.
三種子組件的模板類型
字符串模板(string template):
Vue.component('my-component', {
template: '<span>{{ message }}</span>',
data: {
message: 'hello'
}
})
直接將子組件模板定義在「子組件標(biāo)簽」中的 Inline Templates:
<my-component inline-template>
<div>
<p>These are compiled as the component's own template.</p>
<p>Not parent's transclusion content.</p>
</div>
</my-component>
定義在 <script> 標(biāo)簽中的 X-Templates:
<script type="text/x-template" id="hello-world-template">
<p>Hello hello hello</p>
</script>
Vue.component('hello-world', {
template: '#hello-world-template'
})
全局訪問(wèn)子組件
在 Chrome 的 Console 里面調(diào)試的時(shí)候滞磺,直接能夠訪問(wèn)到子組件是有一定需求的,這里可以用 ref 屬性來(lái)實(shí)現(xiàn):
<div id="parent">
<user-profile ref="profile"></user-profile>
</div>
正常實(shí)例化以后就可以這樣訪問(wèn):
var parent = new Vue({ el: '#parent' })
// access child component instance
var child = parent.$refs.profile
Slot
還沒(méi)有實(shí)際遇到莱褒,等后面補(bǔ)充