Vue-element-plus 環境配置

從 React 轉成 Vue 馬上就踩雷。

簡述

當初是看 官方文件 來配置的,不過我自己覺得實在是寫得有點亂,因為當時的主流都是以 Vite 為主,而 Vue-CLI 的相關資料就顯得少蠻多的。

總之呢,這篇會以 Vue-CLI 的角度來寫一篇更好懂的教學來記錄一下,也順便解釋一些基本觀念。

前備知識

當初在配置時花了一段時間才搞好,這是因為 Vue 跟 React 在引入 UI 元件的方式有點不太一樣,所以我想先在這邊解釋一下差別。

首先在 React 中如果要使用 Mui,我們通常是這樣做:

1
2
3
4
5
6
import * as React from 'react'
import Button from '@mui/material/Button'

function App() {
return <Button variant='contained'>Hello World</Button>
}

React 的做法是「直接在元件中把 UI 元件引入」。以我自己的角度而言這是很直覺的方式,畢竟就是直接 import 進來用嘛?

而 Vue 除了直接在 SFC 中引入以外,還有一種更簡潔的做法,這邊拿 element-plush 來舉例。

直接在 SFC 中引入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<template>
<nav>
<el-button type="primary">Hello</el-button>
</nav>
<router-view />
</template>

<script>
import { ElButton } from 'element-plus'

export default {
components: { ElButton }
}
</script>

雖然這樣做也可行,不過你應該會更常看到下面這種寫法:

1
2
3
4
5
6
7
8
9
10
import { createApp } from 'vue'
import App from './App.vue'
import { ElButton } from 'element-plus'
import 'element-plus/dist/index.css'

const app = createApp(App)
// 註冊(元件名稱,元件)
app.component(ElButton.name, ElButton)
app.use(router)
app.mount('#app')

這個作法是直接「在 Vue 實體上註冊(Register)全域元件」。

意思就是所有的 SFC 中可以直接使用 <el-button>,不用再做引入的動作。

這應該算是 Vue 的特色吧,雖然一開始覺得這好搞剛,不過多寫一段時間後就會覺得這樣其實也不錯。

總之如果你是用 Vue 的 UI library,你基本上都會看到第二種寫法,只是想解釋一下這背後的原因是什麼。

安裝依賴項目

這邊先用 Vue-CLI 的 create <project> 建立好以後再來安裝:

1
npm element-plus

引入

引入的方式有兩種,分別為「全部引入」跟「按需引入」。

這裡順便提一個小知識,我們在 import 套件時雖然都會寫成 import { ElButton } from 'element-plus' 這樣的形式,不過實際上的路徑是對應到 node_modules/element-plus/lib/index 這個位置。

總之如果等一下引入部分你發現有問題,可以試著檢查看看是不是路徑不對,通常有 90% 都是因為這樣子,試著自己 debug 看看吧!

全部引入

意思就是一次把所有元件都引入:

1
2
3
4
5
6
7
8
9
10
11
12
13
// main.js
import { createApp } from 'vue'
import App from './App.vue'
// css
import 'element-plus/dist/index.css'
// components (all)
import ElementPlus from 'element-plus'

const app = createApp(App)
// register
app.use(ElementPlus)
app.use(router)
app.mount('#app')

不管是 CSS 還是元件都直接全部引入,接著就可以直接在元件中使用了。這招最簡單,但缺點就是你如果你用的數量不多的話會顯得浪費。

按需引入

這邊是我覺得文件中寫的最麻煩的地方,一開始就要你安裝一堆套件跟調整 webpack。

這邊我想先介紹一下最簡單的方式,這邊你不需要安裝任何東西,只要先這樣寫就好:

1
2
3
4
5
6
7
8
9
10
11
12
13
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { ElButton } from 'element-plus'
// css
import 'element-plus/dist/index.css'

const app = createApp(App)
// register
app.component(ElButton.name, ElButton)
app.use(router)
app.mount('#app')

其實就是把需要的元件拿出來用而已,而不是整包拿出來。

不過這邊應該會注意到 CSS 的部分是引入 index.css,有沒有辦法只引入 Elbutton 會用到的 CSS 就好?

有,這個就是文件裡面要你安裝各種套件跟調整設定的原因。如果你沒有很在意「體積」的問題的話,底下的部分你可以略過,因為完全沒有必要。

總之這樣子做的用意是降低容量,根據我實測的結果來看最多可以減少個 100KB 左右吧(看你實際用的多或少),所以這個就看真的看個人需求來決定了

首先來安裝新的包:

1
npm i unplugin-element-plus -D

接著調整 vue.config.js

1
2
3
4
5
6
7
8
9
10
module.exports = defineConfig({
// ...
configureWebpack: {
plugins: [
require('unplugin-element-plus/webpack')({
// options
})
]
}
})

附註:關於 options 的部分想知道更多可以參考文件

這個包的用途就是在我「引入元件時也自動引入對應的 CSS 檔案」,像這樣:

1
2
3
4
5
6
// 我看起來只引入了這個
import { ElButton } from 'element-plus'

// 但實際會在背後幫我多引入 CSS 檔案
import { ElButton } from 'element-plus'
import 'element-plus/es/components/button/style/css'

看到這邊你應該也理解為什麼要有這個套件了吧?畢竟妳不可以每用一個元件就去找出對應的 CSS 來引入,怎麼想都太麻煩了,所以才會寫成套件來處理。

OK,到這邊以後基本上就配置好環境了,最後會來討論一下優化的部分。

最後的優化

看到這邊你應該已經知道怎麼「按需引入」需要的東西了,不過我想介紹一個更優雅的寫法,畢竟你應該不會想像這樣子把所有東西都寫在 main.js 裡:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import {
ElInput,
ElForm,
ElFormItem,
ElButton,
ElMessage,
ElNotification
// ...
} from 'element-plus'

const app = createApp(App)

// register component
app.component(ElInput.name, ElInput)
app.component(ElForm.name, ElForm)
app.component(ElFormItem.name, ElFormItem)
app.component(ElButton.name, ElButton)
// register plugin
app.use(ElMessage)
app.use(ElNotification)

app.use(router)
app.mount('#app')

附註:plugin 指的是像 ElNotification 這種屬於 function 而不是元件的東西。

所以你可以建立一個 src/plugins/elementui.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import {
ElInput,
ElForm,
ElFormItem,
ElButton,
ElMessage,
ElNotification,
// ...
} from 'element-plus'

// components
export const elComponents = [ElInput, ElForm, ElFormItem, ElButton, ...]

// plugins
export const elPlugins = [ElMessage, ElNotification, ...]

接著在 main.js 的時候就可以乾淨很多:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { elComponents, elPlugins } from './plugin/elementui'

const app = createApp(App)

// register component
elComponents.forEach((c) => {
app.component(c.name, c)
})
// register plugin
elPlugins.forEach((p) => {
app.use(p)
})

app.use(router)
app.mount('#app')
Vue-事件基礎 JavaScript-實作下載檔案的方式
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×