--- tags: VUE 3 課程筆記 --- # VUE 3 課程筆記 (七) Vue CLI ## what is Vue CLI? ### 為什麼要用 Vue CLI 1. 前端開發越來越複雜,每個開發者習慣亦有很大不同,因此整合性的框架工具,可以減少彼此開發上的差異。 2. 編譯環境的複雜,缺乏整合工具將會在每次專案都為了建立環境花很多時間。 3. 前後端分離形成主流, SPA 更符合開發習慣。 4. 可以讓套件引用更好管理。 ### 什麼是 Vue CLI 1. 是一種基於 webpack 打包所建置的開發工具 (webpack 就是一種可以將 .vue .sass .ts ... 等很多種檔案 編譯成瀏覽器可以看懂的 .html .css .js 檔案的工具) 2. 能更方便地管理與載入第三方套件 (Bootstrap5、Vue Router...) 3. 可以運行 Sass,Babel 等編譯工具,讓開發更方便 4. 可以建立 .vue 的檔案,讓元件的 HTML、CSS、JavaScript 可以整理在同一個檔案裡面 5. 運用元件的應用,讓 SPA 更方便開發 ### 傳統路由 vs SPA 傳統路由: 每次進入新頁面都會完整的載入一次整個頁面 網址會是 https://www.XXX.com/XXX SPA: 第一次載入就載入好頁面,後面每次換頁面的時候網頁同樣部分的地方不會渲染,都只會是頁面中一小區塊進行渲染 網址會是 https://www.XXX.com/#/XXX ### 更好地實現前後端分離 網頁跟後端資料完全拆分,只會用跟後端討 API 的方式針對要渲染的部分進行資料更新 ### 關於 CLI 完整的是 Command-Line Interface 就是命令列介面的意思,大概就是用命令提示字元 & 終端機之類的程式用指令去操作的介面。 ## 章節資源 NodeJS 官方網站連結:[https://nodejs.org/en/](https://nodejs.org/en/) Vue CLI: [https://cli.vuejs.org/zh/guide/](https://cli.vuejs.org/zh/guide/) Vue Router: [https://next.router.vuejs.org/zh/index.html](https://next.router.vuejs.org/zh/index.html) Vue Axios: [https://www.npmjs.com/package/vue-axios](https://www.npmjs.com/package/vue-axios) ## 安裝 Vue Cli 請使用 Nodejs 8.9 以上版本 安裝指令是 ``` npm install -g @vue/cli ``` macOS 需要加一個 ```sudo``` 在最前面,突破權限。 這邊如果安裝完 輸入 ```vue -V``` 有跳出 ```@vue/cli 版本號```那就恭喜安裝成功啦 cd 到想要建立環境的資料夾,然後使用```vue create XXX資料夾名稱``` 就可以創建一個 Vue Cli 環境資料夾 這邊選擇 ```Manually select features``` 手動安裝 裡面就選一選要選的選項 ![](https://i.imgur.com/u4ForXB.png) 哦對,提醒一下 space 選擇, enter 進入下一題 ## Vue CLI 環境中的檔案說明 ![](https://i.imgur.com/HgI1Vvl.png) ### node_modules npm 安裝的套件都在這邊 ### public 跟進入點沒有相關連,或不需要編譯的檔案 #### index.html head要編輯在這個檔案編輯 ### src 這是主要撰寫整理的地方 #### assets 相關的其他資產,比較小的圖片,其他的 CSS 或者相關的 JS 檔案都放在這邊 #### components 元件放在這邊 #### router 路由表在這邊設定 #### views 頁面會在這個檔案裡 #### App.vue mian.js 生成的第一個主要元件 #### main.js 這個是整個專案的進入點,router、views、components、套件、全域設定檔案 等等的檔案都會依照層級匯入到這裡,沒有在層級匯入這個檔案的話,就不會被編譯 ### .browserslistrc 瀏覽器預期要支援的版本,裏面會去設定符合主流瀏覽器的編譯 ### .editorconfig 編輯器撰寫風格的設定檔案 ### .eslinttrc.js eslint 的設定檔案,調整 eslint 規則的地方 ### .gitignore 在 git 裡面需要去忽略的檔案有哪些 ### babel.config.js babel的設定檔案 ### package-lock.json 實際上安裝的套件版本以及描述 ### package.json 這個專案的配置檔案,裏面有這個專案有安裝哪些套件 ### README.md 就是一個進入新的專案的操作步驟跟指令介紹檔案 ### vue.config.js ## 如何在 CLI 環境中加入 Vue 元件 ### 先講一下可能會遇到的問題 #### 問題一: bootstrap 裝不進去超火 der ![](https://i.imgur.com/q0Xmhud.png) 解決方案:用一個強制安裝的方式 ```npm install --force``` (The -f or --force argument will force npm to fetch remote resources even if a local copy exists on disk) 直接硬下載進去,目前掛載起來沒啥問題,解決! #### 問題二: 檔案命名的小細節 解決方案:.vue 檔案命名規則是開頭大寫,然後必須要兩個字元,所以檔案名稱會是像這樣```HelloWorld.vue```不過如果硬要用一個單字當檔案名稱就會報錯給你看,這時候如果覺得非得要單一個單字當檔案才爽的話,就去```.eslintrc.js```檔案裡面改設定,修改方式如下 ```javascript= module.exports = { root: true, ... rules: { // 加上這行 'vue/multi-word-component-names': ['error', { ignores: ['Hello'] }] } } ``` 這樣檔案就可以只```Hello.vue```了哦 ### 接下來開始記錄寫元件的部分 #### step1. 在 components 資料夾中建立一個 .vue 元件檔案 命名規則起記得問題二的教訓 #### step2. 開始寫這個元件,架構大概長這樣: ```htmlembedded= <template> HTML 內容 . . . </template> <script> export default { data () { return { . . . }, methods: { . . . }, 生命週期 () { . . . } } } </script> <style lang="scss"> SCSS 內容 . . . </style> ``` #### step3. 寫好之後,就可以把這個元件掛載到想掛載的頁面裡面 例如,AboutView.vue 的頁面檔案中: ```htmlembedded= <template> <div class="about"> <h1>This is an about page</h1> </div> <元件名稱></元件名稱> </template> <script> // 先引入檔案 import 元件名稱 from '@/components/元件名稱.vue' export default { // 掛載元件 components: { 元件名稱 } } </script> ``` 然後稍微注意一下 eslint 報錯,順便調整一下自己的撰寫習慣,完成! ## CLI 引入外部套件 首先使用 ```npm install```依照套件官方文件進行安裝 ### 在 ```Main.js``` 當中進行外部套件的全域註冊 ```htmlembedded= // 本來就在檔案裡面的 import {createApp} from 'vue'; // 匯入 vee-validate 主套件 import { Field, Form, ErrorMessage, defineRule, configure, }from 'vee-validate'; // 匯入 vee-validate 相關規則 import {require, email, min }from '@vee-validate/rules'; // 匯入多國語系的功能 import {localize, setLocale} from '@vee-validate/i18n'; // 匯入繁體中文語系檔案 import zhTW from '@vee-validate/i18n/dist/locale/zh_TW.json' // 本來就在檔案裡面的 import App from './App.vue'; import router from './router'; // 定義驗證規則 defineRule('required', required); defineRule('email', email); defineRule('min', min); // 設定 vee-validate 全域規則 configure({ generateMessage: localize({ zh_TW: zhTW }), // 載入繁體中文語系 validateOnInput: true, // 當輸入任何內容直接進行驗證 }); // 設定預設語系 setLocale('zh_TW'); // 把原本的程式碼改寫成方便掛載的樣子 const app = createApp(App).use(router); // 註冊 vee-validate 三個全域元件 app.component('VForm', Form); app.component('VField', Field); app.component('ErrorMessage', ErrorMessage); app.mount('#app'); ``` 注:這邊測試,全域註冊單純只用 Form / Field 的檔案名稱,還是會被命名規則卡住,所以還是用回 VForm & VField ### 在.vue 檔案裡面使用套件 ```htmlembedded= <template> <div class="home"> // 引入 VForm 元件 <VForm v-slot="{ errors, values, validate }" @submit="onSubmit"> {{ errors }} {{ values }} <div class="mb-3"> <label for="email" class="form-label">Email</label> // 引入 VField 的 input 元件 // 這邊要用 v-model 雙向綁定到 data 的 user.mail 存資料 <VField id="email" name="email" type="email" class="form-control" :class="{ 'is-invalid': errors['email'] }" placeholder="請輸入 Email" rules="email|required" v-model="user.email"></VField> // 引入 ErrorMessage 錯誤訊息提示 <ErrorMessage name="email" class="invalid-feedback"></ErrorMessage> </div> <button class="btn me-2 btn-outline-primary" type="button" @click="validate">驗證</button> <button class="btn btn-primary" type="submit">Submit</button> </VForm> </div> </template> <script> export default { name: 'Home', data() { return { // 要有一個可以存放 user 資料的地方 user: {}, }; }, methods: { onSubmit() { console.log(this.user); }, }, created() { console.log(this); }, }; </script> ``` ## 環境變數 因應開發需求可以存取的環境變數 有分為: ```htmlmixed= .env // 一般環境變數 在所有環境中被載入 .env.local // 存在本地端的環境變數 在所有環境中被載入,但會被 git 忽略 .env.development // 開發時使用的環境變數 只在指定的模式中被載入 .env.production // 上線用的環境變數 只在指定的模式中被載入 ``` 環境變數的撰寫方式: 1. 在資料夾中直接新增一隻 .env 的檔案 2. 環境變數的開頭是固定的: ```htmlembedded= VUE_APP_自定義名稱 = 變數變數變數變數變數 ``` 要在頁面&元件檔案中使用的話,請在 data(){} 裡面加入 ```javascript= data(){ return{ XXX: process.env.VUE_APP_自定義名稱 } } ``` ## Vue CLI 編譯設定檔 可以先新增一隻 ```.env.production```的檔案將變數改為編譯完之後使用的變數,這樣開發階段使用的變數就會被替換掉,舒服! 再來,需要在 ```vue.config.js```這隻檔案裡面調整輸出路徑以確保編譯後的檔案的路徑是有互相對應到的 請調整成下面這樣: ```javascript= module.exports = { publicPath: '/dist/' } ``` 這樣在編譯完成的檔案根目錄就會從 dist 開始,就不會發生找不到檔案的情況囉~