跳至主要内容

[Vue] 元件製作及註冊

TL;DR

參考資料

相關連結


元件介紹

在Vue中,會將各個區塊拆分成不同的元件。在最上層的#app掛載的其實也是一個元件。

拆分成元件有以下好處:

  1. 方便維護
    當把所有的程式碼撰寫在一支檔案中時,程式碼會非常冗長,當需要維護時會不好管理。

    一般建議單支檔案不要超過200行,最多300行不能再多了!

  2. 版控避免衝突產生
    在使用版本控制時(如git),拆分成不同的檔案也可以避免造成文件上的衝突。每個人只需要專注在各自元件的檔案即可。

  3. 資料拆分
    在不同的元件中,所定義的data是獨立的。就算變數名稱相同,裡面存放的內容也可以不同。

  4. 可巢狀管理
    元件中還可以再插入元件。

    ps:如果在上下元件需要傳遞資料,則需另外使用props及emit來完成傳遞。後續會再介紹。

註冊元件

註冊元件分為全域註冊以及區域註冊

而在註冊元件時,特點如下:

  1. 元件需要在 createApp 後,mount 前進行定義
  2. 元件需指定一個名稱
  3. 元件結構與最外層的根元件結構無異(除了增加 Template 的片段)
  4. 元件另有 prop, emits 等資料傳遞及事件傳遞

全域註冊

因為需要在createApp之後,mount之前進行定義,所以起手式會有一點差異

使用全域註冊的元件,則所有子元件都可以使用該元件。常使用於中小型專案,一般頁面開發。

全域註冊語法
vue.js
const app=Vue.createApp({
// 根元件內容
data,
methods,
template,
components
...etc
})

app.component('元件名稱',{
// 元件內容
data,
methods,
template,
components
...etc
});

app.mount('#app');
<div id="app">
<div class="p-5">
<h4>
全域註冊
</h4>
<p>此 createApp 下,任何子元件都可運用,在中小型專案、一般頁面開發很方便</p>
<alert></alert>
<alert2></alert2>
<alert3></alert3>
</div>
</div>

區域註冊

區域註冊的特點為,只能在註冊的元件內使用該註冊的元件。

區域註冊語法
vue.js
const localcomponent = {
data,
methods,
template,
...
}
const app = Vue.createApp({
data(){...},
methods:{...},
components:{
localcomponent
}
})
<div id="app">
<div class="p-5">
<h4>區域註冊</h4>
<p>限制在特定元件下才可使用,在 Vue Cli 中很常使用此方法(便於管理)</p>
<hr>
{{text}}
<alert2></alert2>
<alert1></alert1>
</div>
</div>

可以看到 Line:31(Vue) 內的alert2元件並沒有正確顯示。這是因為alert2元件並沒有在alert1中註冊。

但是因為alert1是全域註冊的關係,所以 Line:9(Vue) 內的alert1可以正確顯示在alert2內。

區域註冊命名限制

命名限制

使用小駝峰命名時,如果沒有正確掛載到畫面上,可以使用將小駝峰轉換為 - 連接的方式(與style綁定類似)

<div id="app">
<div class="p-5">
<h4>命名限制</h4>
<localtest></localtest>
<local-component2></local-component2>
</div>
</div>

外部檔案匯入元件

使用ESM的export default 與 import variableName from 'PATH' 來將外部元件給匯入

匯入完畢之後,使用方法與區域註冊相同。

component.js
export default {
data() {
return {
text: '這是模組化元件'
};
},
template: `<div class="alert alert-primary" role="alert">
{{ text }}
</div>`
}
vue.js
import moduleComponent from './component.js';
const app = Vue.createApp({
data() {
return {
text: '根元件 的 text',
};
},
components:{
moduleComponent
}
})

元件樣板

註冊元件使用的方法為最基本的,直接在元件中建立該元件的樣板。

建立樣板的方式有以下幾種:

  1. template
    註冊元件中使用的方法,直接在元件中撰寫樣板。
  2. x-template
    使用另一個script撰寫(但是需給予id辨識),方便管理。
  3. 單文件元件
TBD

待補完整

template

直接在元件物件內直接撰寫該元件的樣板,屬性為template,值為字串(使用樣板字面值 ``

vue.js
const localComponent={
data(){
return {
text: 'localComponent'
}
},
template: `
<div class="alert alert-primary" role="alert">
{{ text }}
</div>
`
}

x-template

另外在檔案中撰寫一個script,設定該script的typeid後,在vue.js中的元件物件內使用template:'#scriptID'對應。即可正確抓取該樣板

index.html
<!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:14script需要補上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');

標籤名稱掛載元件

可以直接使用標籤名稱將元件給掛載到畫面上。

html(#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>

動態屬性切換元件

使用v-is時,可以傳入變數。透過動態改變變數的內容,可以做到切換要渲染到畫面上的元件。

<div id="app">
<div class="p-5">
<div class="mb-3">目前的componentName值:{{componentName}}</div>
<input type="text" v-model.lazy="componentName" class="form-control">
<div id="help" class="form-text">將input內容改為alert2試試看</div>
<div v-is="componentName" class="mt-3"></div>
</div>
</div>

v-bind:is

note

v-bind:is是由Vue2而來的,建議直接使用v-is指令即可。

在使用v-bind:is時,需要在component標籤中才可以正確使用。

<component v-bind:is="componentName"></component>
// 上下兩者結果相同
<div v-is="'componentName'"></div>

html限制應用

在表格中,<tbody>內只能接受<tr>。如果沒有使用<tr>會被因為html的限制,而被移除到表格外。

這時候就可以使用<tr v-is="'componentName'">避免這個限制。

<div id="app">
<div class="p-5">
<table>
<thead>
<tr>
<th>標題</th>
<th>內文</th>
</tr>
</thead>
<tbody>
<!--使用table-row的標籤會被移除到table外-->
<table-row></table-row>
<tr v-is="'table-row'"></tr>
</tbody>
</table>
</div>
</div>