component
作用Vue 的模組 component
是可以重複使用的 Vue 實例,所以也擁有 data
、computed
、watch
、methods
以及生命周期鉤子等,目的是可以將網頁分割成不同區塊以便管理。
這邊介紹的是全域註冊的模組,區域俟深入 component
時再行介紹。
Vue.component('註冊名稱',{模組內容})
component
內的 data
必須是函式如果 component
內的 data
使用物件,就會出錯。
component
內的 data
使用物件,會出現錯誤提示 data
須使用 function
。
並且會找不到錯誤的 data
裡的值。
component
內的 data
須使用函式取得一個獨立的位址(重新賦值),不受其他物件的影響。
template
只能有一個根元素如果在 component
的 template
裡有多個元素的話,就必須利用一個根元素將所有元素包裹起來,否則就會出錯。
錯誤寫法(沒有根元素或 data
使用物件):
//template
<button type="button" @click="counter++">增加</button>
<p>counter:{{counter}}</p>
//data
data:{...}
應改成
//template
<div>
<button type="button" @click="counter++">增加</button>
<p>counter:{{counter}}</p>
</div>
//data
data(){return{}}
component
範例// 單個元素
Vue.component("button-counter", {
template: `
<button type="button" @click="counter++">counter:{{counter}}</button>`,
data(){
return {
counter: 0
}
}
})
// 多個元素
Vue.component("button-counter2", {
template: `
<div>
<button type="button" @click="counter++">增加</button>
<p>counter:{{counter}}</p>
</div>`,
data() {
return {
counter: 0
};
}
});
每個被使用的模組都是一個新的 Vue 實例,也都擁有自己的 data
、computed
、watch
、methods
以及生命周期鉤子等,不會互相干擾彼此的資料。
<div id="vm">
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
只要記得上到下(外到內)用 props
,下到上(內到外)用 $emit
就可以了。
props
向內層模組傳送資料資料不是 component
本身自己擁有的,而是透過外層給予的時,就必須使用 props
來取得資料。
props
就是自定義的 HTML Attribute ,代表著必須要先定義(註冊)才能使用。
props
:定義props
將自定義的 HTML Attribute 註冊在 component
內的 props
中,例如下方的 plan
就是我定義的一個 HTML Attribute ,記得利用陣列註冊 HTML Attribute 的話,要使用字串註冊。
//定義
Vue.component("my-plan", {
props:['plan']
});
設定 props
的值
在 component
內的 props
中註冊好自定義的 HTML 屬性後,就可以在 HTML 中使用該 component
的地方加入這個屬性並給予值,如下,加入 plan
屬性並給予值 go to market
。
<my-plan plan="go to market"></my-plan>
使用 props
的值
使用 props
的值跟使用 data
的方法相同,只不過 props
的值是從外面傳入的(就是在 HTML 中設定的值),如上在 HTML 中,給予 plan
的值就是 go to market
,所以可以把 props
當成另一類的 data
來使用。
Vue.component("my-plan", {
props:['plan'],
template: `
<div>
<p>{{counter}}</p>
<p>{{plan}}</p>
</div>`,
data(){
return {
counter: 0
}
}
});
透過 v-bind
來傳遞 props
的值
如果 props
的值是從外層的 data
中產生的就必須使用 v-bind
,就如同之前所說把 props
當成一般的 HTML Attribute 看待,因此當該 Attribute 需要使用到 Vue 實例裡的資料時就必須使用 v-bind
,讓 Vue 知道這邊使用的資料不是單純的字串,而是 Vue 實例裡的 data
。
<my-plan v-for="plan of plans" :plan="plan" :key="plan"></my-plan>
<script>
Vue.component("my-plan", {
props:['plan'],
template: `
<div>
<p>{{plan}}</p>
</div>`,
});
const vm = new Vue({
el: "#vm",
data:{
plans:['go swimming','see a movie','study']
}
});
</script>
$emit
向外層模組傳送資料在模組內觸發了某個事件,再透過 $emit
傳送自定義的事件名稱到外層,最後透過這個自定義的事件去觸發外層的函式。
<p :style={fontSize:`${emitFontSize}em`}>使用 `$emit`</p>
<my-emit @large-text="emitFontSize+=0.1"></my-emit>
<script>
Vue.component("my-emit", {
template: `
<div>
<button type="button" @click.prevent="$emit('large-text')">加大文字</button>
</div>`
});
const vm = new Vue({
el: "#vm",
data:{
emitFontSize:0.8
}
});
</script>
$emit
資料傳遞分為幾個階段:
component
內利用 v-on
監聽鍵盤、滑鼠或其他事件。$emit('自定義事件名稱')
事件到外層。v-on
監聽並觸發自定義事件名稱
事件。$emit
參數傳遞$event
取得參數值<my-emit @large-text="emitFontSize+=$event"></my-emit>
<script>
Vue.component("my-emit", {
template: `
<div>
<button type="button" @click.prevent="$emit('large-text', 0.2)">加大文字</button>
</div>`
});
const vm = new Vue({
el: "#vm",
data:{
emitFontSize:0.8
}
});
</script>
外層使用 $event
即可取得 $emit
的第2個參數值。
自定義事件被觸發後,$emit('自定義事件', 參數2)
的第2個參數即會被當成引數帶入被執行的函式的參數。
<my-emit @large-text="enlargeText"></my-emit>
<script>
Vue.component("my-emit", {
template: `
<div>
<button type="button" @click.prevent="$emit('large-text', 0.2)">加大文字</button>
</div>`
});
const vm = new Vue({
el: "#vm",
data:{
emitFontSize:0.8
},
methods:{
enlargeText(amount){
console.log(amount)
this.emitFontSize += amount
}
}
});
</script>
如上,當自定義事件 large-text
被觸發後,就會執行函式 enlargeText
,而 $emit('large-text', 0.2)
中的 0.2
就會被代入到函式 enlargeText
的參數 amount
中。
slot
傳送內容在 component
中透過 <slot></slot>
把 HTML 中該 component
所包裹的值代入。
<my-slot>
<p>Using slot</p>
</my-slot>
<script>
Vue.component("my-slot", {
template: `
<div>
<slot></slot>
</div>`
});
</script>
Demo:[DAY10]跟 Vue.js 認識的30天 - Vue 的模組
參考文件:
Vue.js Components Fundamentals