[Vue] 元件製作及註冊
TL;DR
參考資料
相關連結
元件介紹
在Vue中,會將各個區塊拆分成不同的元件。在最上層的#app
掛載的其實也是一個元件。
拆分成元件有以下好處:
-
方便維護
:
當把所有的程式碼撰寫在一支檔案中時,程式碼會非常冗長,當需要維護時會不好管理。一般建議單支檔案不要超過200行,最多300行不能再多了!
-
版控避免衝突產生
:
在使用版本控制時(如git
),拆分成不同的檔案也可以避免造成文件上的衝突。每個人只需要專注在各自元件的檔案即可。 -
資料拆分
:
在不同的元件中,所定義的data是獨立的。就算變數名稱相同,裡面存放的內容也可以不同。 -
可巢狀管理
:
元件中還可以再插入元件。ps:如果在上下元件需要傳遞資料,則需另外使用props及emit來完成傳遞。後續會再介紹。
註冊元件
註冊元件分為全域註冊以及區域註冊。
而在註冊元件時,特點如下:
- 元件需要在 createApp 後,mount 前進行定義
- 元件需指定一個名稱
- 元件結構與最外層的根元件結構無異(除了增加 Template 的片段)
- 元件另有 prop, emits 等資料傳遞及事件傳遞
全域註冊
因為需要在createApp之後,mount之前進行定義,所以起手式會有一點差異
使用全域註冊的元件,則所有子元件都可以使用該元件。常使用於中小型專案,一般頁面開發。
const app=Vue.createApp({
// 根元件內容
data,
methods,
template,
components
...etc
})
app.component('元件名稱',{
// 元件內容
data,
methods,
template,
components
...etc
});
app.mount('#app');
- html(#app)
- vue
<div id="app">
<div class="p-5">
<h4>
全域註冊
</h4>
<p>此 createApp 下,任何子元件都可運用,在中小型專案、一般頁面開發很方便</p>
<alert></alert>
<alert2></alert2>
<alert3></alert3>
</div>
</div>
const app = Vue.createApp({
data() {
return {
text: '外部元件文字',
};
},
}).component('alert', {
// 全域註冊方法1
data() {
return {
text: 'alert 的 text'
};
},
template: `<div class="alert alert-primary" role="alert">
{{ text }}
</div>`
});
// 全域註冊方法2
app.component('alert2',{
data() {
return {
text: 'alert2 的 text'
};
},
template: `<div class="alert alert-primary" role="alert">
{{ text }}
</div>`
});
// 也可以事先先定義好物件
// 但是需要注意要在前面就定義好,否則會取不到
const alert3 = {
data() {
return {
text: '元件3'
};
},
template: `<div class="alert alert-primary" role="alert">
{{ text }}
</div>`
}
app.component('alert3',alert3);
// 最後才會將元件掛載在#app上
app.mount('#app');
區域註冊
區域註冊的特點為,只能在註冊的元件內使用該註冊的元件。
const localcomponent = {
data,
methods,
template,
...
}
const app = Vue.createApp({
data(){...},
methods:{...},
components:{
localcomponent
}
})
- html(#app)
- vue
<div id="app">
<div class="p-5">
<h4>區域註冊</h4>
<p>限制在特定元件下才可使用,在 Vue Cli 中很常使用此方法(便於管理)</p>
<hr>
{{text}}
<alert2></alert2>
<alert1></alert1>
</div>
</div>
const alert2 = {
data() {
return {
text: '元件2'
};
},
template: `<div class="alert alert-primary" role="alert">
{{ text }}
<alert1></alert1>
</div>`
}
const app = Vue.createApp({
data() {
return {
text: '根元件 的 text',
};
},
components:{
alert2
}
})
// 全域註冊方法2
app.component('alert1',{
data() {
return {
text: '元件1'
};
},
template: `<div class="alert alert-primary" role="alert">
{{ text }}
<alert2></alert2>
</div>`
});
app.mount('#app');
可以看到 Line:31(Vue) 內的alert2元件並沒有正確顯示。這是因為alert2元件並沒有在alert1中註冊。
但是因為alert1是全域註冊的關係,所以 Line:9(Vue) 內的alert1可以正確顯示在alert2內。
區域註冊命名限制
使用小駝峰命名時,如果沒有正確掛載到畫面上,可以使用將小駝峰轉換為 -
連接的方式(與style綁定類似)
- html(#app)
- vue
<div id="app">
<div class="p-5">
<h4>命名限制</h4>
<localtest></localtest>
<local-component2></local-component2>
</div>
</div>
const localComponent1={
data(){
return {
text: 'localComponent1'
}
},
template: `<div class="alert alert-primary" role="alert">
{{ text }}
</div>`
}
const localComponent2={
data(){
return {
text: 'localComponent2'
}
},
template: `<div class="alert alert-primary" role="alert">
{{ text }}
</div>`
}
const app = Vue.createApp({
data() {
return {
text: '根元件 的 text',
};
},
})
// 不要使用大寫名稱
app.component('localtest',localComponent1);
// 如果一定要使用的話
// 在html中記得轉換為<local-component2></local-component2>
app.component('localComponent2',localComponent2);
app.mount('#app');
外部檔案匯入元件
使用ESM的export default 與 import variableName from 'PATH' 來將外部元件給匯入
匯入完畢之後,使用方法與區域註冊相同。
export default {
data() {
return {
text: '這是模組化元件'
};
},
template: `<div class="alert alert-primary" role="alert">
{{ text }}
</div>`
}
import moduleComponent from './component.js';
const app = Vue.createApp({
data() {
return {
text: '根元件 的 text',
};
},
components:{
moduleComponent
}
})
元件樣板
在註冊元件使用的方法為最基本的,直接在元件中建立該元件的樣板。
建立樣板的方式有以下幾種:
template
:
註冊元件中使用的方法,直接在元件中撰寫樣板。x-template
:
使用另一個script撰寫(但是需給予id辨識),方便管理。單文件元件
:
待補完整
template
直接在元件物件內直接撰寫該元件的樣板,屬性為template
,值為字串
(使用樣板字面值 ``
)
const localComponent={
data(){
return {
text: 'localComponent'
}
},
template: `
<div class="alert alert-primary" role="alert">
{{ text }}
</div>
`
}
x-template
另外在檔案中撰寫一個script,設定該script的type
及id
後,在vue.js中的元件物件內使用template:'#scriptID'
對應。即可正確抓取該樣板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<xtemplate></xtemplate>
</div>
<!-- 作為x-template使用的script -->
<script type="text/x-template" id="alert-x-template">
<div class="alert alert-primary" role="alert">
from x-template
</div>
</script>
<script type="module">
const app = Vue.createApp({
...
})
app.component('xtemplate', {
template:'#alert-x-template'
});
app.mount('#app');
</script>
</body>
</html>
Line:14 需要設定一個與 Line:25 對應的id
。
並且 Line:14 的script
需要補上type="text/x-template"
。
元件的使用
前面介紹如何註冊元件,現在要開始介紹元件可以怎麼使用。
以下使用時所使用的範例為:
const app = Vue.createApp({
data() {
return {
componentName: 'alert1'
};
}
})
app.component('alert1', {
template: `<div class="alert alert-primary" role="alert">
範例ㄧ
</div>`,
});
app.component('alert2', {
template: `<div class="alert alert-primary" role="alert">
範例二
</div>`,
});
app.mount('#app');
標籤名稱掛載元件
可以直接使用標籤名稱將元件給掛載到畫面上。
<div id="app">
<alert1></alert>
</div>
搭配 v-for
<div id="app">
<!-- 將alert重複渲染在畫面上3次 -->
<alert1 v-for="i in 3" :key="i"></alert>
</div>
使用
v-for
需要加上唯一值的:key
v-is
使用v-is時,就可以使用div標籤來渲染元件。
使用時需要使用字串傳入元件定義的名稱
<div id="app">
<div v-is="'alert1'"></div>
</div>