跳至主要内容

[Vue] 引用外部套件

TL;DR

在載入套件的時候,可以使用npm或是cdn的方式引入。

載入後,則是可以透過app.use或是元件的方式去啟用。

參考資料

相關連結


CDN載入VeeValidate

官方簡單範例

<div id="app">
<!-- 送出表單時,v-form會自動驗證規則是否符合 -->
<v-form @submit="onSubmit">
<!-- name內的名稱可以自訂,會對應錯誤訊息的name (元件需要加上頭尾標籤)-->
<v-field name="name" type="text" placeholder="Who are you" :rules="isRequired"></v-field>

<!-- name對應v-field上的name -->
<error-message name="name"></error-message>

<button>Submit</button>
</v-form>
</div>
Component命名

因為這邊在Codepen上使用CDN的方式去載入套件,會將VeeValidate賦予到同名稱的變數上。

所以在註冊元件時,需使用VeeValidate.Form,VeeValidate.Field,VeeValidate.ErrorMessage去分別取出三個元件。

並且為了避免元件名稱與html標籤名稱相同,另外賦予一個加上V前綴的名稱( Line:6 ~ Line:8 (Vue))

透過v-slot觀看目前錯誤內容
<v-form @submit="onSubmit" v-slot="all">
{{all}}
<v-field name="name" type="text" placeholder="Who are you" :rules="isRequired">
</v-field>
<error-message name="name"></error-message>
<button>Submit</button>
</v-form>

更多範例

<div id="app">
<div class="p-5">
<h3>範例:載入 VeeValidate 驗證套件</h3>
<v-form @submit="onSubmit" v-slot="{errors}">
{{errors}}
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<!-- 使用veevalidate提供的規則,不需動態綁定,使用rule="..."即可,需要多個規則可以使用|隔開(不能加上空白) -->
<v-field id="email" name="email" type="email" class="form-control"
:class="{ 'is-invalid': errors['email'] }"
rules="email|required"
placeholder="請輸入 Email">
</v-field>
<error-message name="email" class="invalid-feedback"></error-message>
</div>

<!-- 自行練習 -->
<div class="mb-3">
<label for="name" class="form-label">姓名</label>
<v-field id="name" name="姓名" type="text" class="form-control"
placeholder="請輸入姓名"></v-field>
<span class="invalid-feedback"></span>
</div>

<div class="mb-3">
<label for="phone" class="form-label">電話</label>
<!-- 使用自己定義的methods時,需要用動態綁定:rules -->
<!-- name可以設定中文,會與errors的屬性名稱相同,所以透過error['電話']的有無可以切換is-invalid的class -->
<v-field id="phone" name="電話" type="text" class="form-control"
:rules="isPhone"
:class="{ 'is-invalid': errors['電話'] }"
placeholder="請輸入電話"
v-model="user.phone"
>
</v-field>
<error-message class="invalid-feedback" name="電話"></error-message>
</div>

<!-- 自行練習 -->
<div class="mb-3">
<label for="region" class="form-label">地區</label>
<select id="region" name="地區" class="form-control">
<option value="">請選擇地區</option>
<option value="台北市">台北市</option>
<option value="高雄市">高雄市</option>
</select>
<span class="invalid-feedback"></span>
</div>

<!-- 自行練習 -->
<div class="mb-3">
<label for="address" class="form-label">地址</label>
<input id="address" name="地址" type="text" class="form-control"
placeholder="請輸入地址">
<span class="invalid-feedback"></span>
</div>

<button class="btn btn-primary" type="submit">Submit</button>
</v-form>
</div>
</div>
表單的v-model

可以直接在v-field上綁定v-model,會直接修改data內的狀態。

另外也可以如同官方提供的範例,直接在觸發@submit事件時,自訂義要送出時的行為 透過傳入一個values參數,可以將各個參數的值加工後(if needed)傳送到後端。

為單一表單進行驗證(VeeValidate)

VeeValiadation 分為 Cli 與 CDN 版本,本範例以 CDN 為主,觀念上兩者並無太大差異。

文件:

CDN:


  1. 載入外部CDN

    <script src="https://cdnjs.cloudflare.com/ajax/libs/vee-validate/4.5.8/vee-validate.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@vee-validate/rules@4.5.8/dist/vee-validate-rules.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@vee-validate/i18n@4.5.8/dist/vee-validate-i18n.min.js"></script>

  2. 註冊元件

    註冊全域的表單驗證元件(VForm, VField, ErrorMessage)

    const app = Vue.createApp({
    // ...
    });
    app.component('VForm', VeeValidate.Form);
    app.component('VField', VeeValidate.Field);
    app.component('ErrorMessage', VeeValidate.ErrorMessage);

    app.mount('#app');

  3. 定義規則

    選擇加入特定規則,全規則可參考連結:官方@vee-validate/rules

    VeeValidate.defineRule('email', VeeValidateRules['email']);
    VeeValidate.defineRule('required', VeeValidateRules['required']);

    全部加入

    Object.keys(VeeValidateRules).forEach(rule => {
    VeeValidate.defineRule(rule, VeeValidateRules[rule]);
    });

    全部加入(CDN 版本)

    Object.keys(VeeValidateRules).forEach(rule => {
    if (rule !== 'default') {
    VeeValidate.defineRule(rule, VeeValidateRules[rule]);
    }
    });

  4. 加入多國語系

    外部資源儲存到本地,方便稍後使用。

    // 讀取剛剛存取的外部的資源
    VeeValidateI18n.loadLocaleFromURL('./zh_TW.json');

    // Activate the locale
    VeeValidate.configure({
    generateMessage: VeeValidateI18n.localize('zh_TW'),
    validateOnInput: true, // 調整為:輸入文字時,就立即進行驗證
    });

  5. 套用v-form並加入v-slot

    <v-form v-slot="{ errors }" @submit="onSubmit" >

    備註:v-slot 稱為插槽 Props,可以將驗證結果的回饋資料直接帶入於區塊中

  6. 套用v-fielderror-message

    常用技巧:

    • name 為必填,是錯誤驗證的回饋欄位,會與多個項目進行匹配(errors, errors-message …)
    • v-field 帶入全域設定的規則,可參考相關文件
    • as 可以改變 v-field 的型態,如以下 select 範例
    • :class可運用v-form帶入的驗證錯誤作為判斷
    <v-field
    id="email"
    name="email"
    type="email"
    class="form-control"
    :class="{ 'is-invalid': errors['email'] }"
    placeholder="請輸入 Email" rules="email|required"
    v-model="user.email"
    ></v-field>
    <error-message name="email" class="invalid-feedback"></error-message>
    select範例
    <v-field
    id="name"
    name="地區"
    class="form-control"
    :class="{ 'is-invalid': errors['地區'] }"
    placeholder="請輸入地區"
    rules="required"
    v-model="user.region"
    as="select"
    >
    <option value="">請選擇地區</option>
    <option value="台北市">台北市</option>
    <option value="高雄市">高雄市</option>
    </v-field>
  7. 加入自訂驗證、送出表單等行為

    範例:自訂驗證 rules 中可自訂函式來驗證結果
    使用 v-bind 綁定 :rules="isPhone"

    <div class="mb-3">
    <label for="phone" class="form-label">電話</label>
    <v-field
    id="phone"
    name="電話"
    type="text"
    class="form-control"
    :class="{ 'is-invalid': errors['電話'] }"
    placeholder="請輸入電話"
    :rules="isPhone"
    v-model="user.phone"
    ></v-field>
    <error-message name="電話" class="invalid-feedback"></error-message>
    </div>
    methods: {
    isPhone(value) {
    const phoneNumber = /^(09)[0-9]{8}$/
    return phoneNumber.test(value) ? true : '需要正確的電話號碼'
    }
    }

    範例:送出表單

    <v-form v-slot="{ errors }" @submit="onSubmit" >
    ...
    <button class="btn btn-primary" type="submit">Submit</button>
    </v-form>
    methods: {
    onSubmit() {
    // ...
    },
    },

VueCLI NPM載入VeeValidate

main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

// 匯入 vee-validate 主套件
import { Field, Form, ErrorMessage, defineRule, configure } from 'vee-validate'

// 匯入 vee-validate 相關規則
import { required, email, min } from '@vee-validate/rules'

// 匯入多國語系的功能
import { localize, setLocale } from '@vee-validate/i18n'

// 匯入繁體中文語系檔案
import zhTW from '@vee-validate/i18n/dist/locale/zh_TW.json'

// 定義驗證規則
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 三個全域元件
// eslint-disable-next-line vue/multi-word-component-names
app.component('Form', Form)
// eslint-disable-next-line vue/multi-word-component-names
app.component('Field', Field)
app.component('ErrorMessage', ErrorMessage)

app.mount('#app')

Vite載入vue-axios

安裝vue-axios

npm install --save axios vue-axios

package.json內容

{
"name": "vite-project",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore",
"format": "prettier --write src/"
},
"dependencies": {
"axios": "^1.6.2",
"pinia": "^2.1.7",
"vue": "^3.3.10",
"vue-axios": "^3.5.2",
"vue-router": "^4.2.5"
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.3.3",
"@vitejs/plugin-vue": "^4.5.1",
"@vue/eslint-config-prettier": "^8.0.0",
"eslint": "^8.49.0",
"eslint-plugin-vue": "^9.17.0",
"prettier": "^3.0.3",
"vite": "^5.0.5"
}
}

調整main.js

src/main.js
import './assets/main.css'

import { createApp } from 'vue'
import { createPinia } from 'pinia'

import axios from 'axios'
import VueAxios from 'vue-axios'

import App from './App.vue'
import router from './router'

const app = createApp(App)

app.use(createPinia())
app.use(router)
app.use(VueAxios, axios)


app.mount('#app')

測試是否載入成功

可以使用Random user來測試是否有正確安裝vue-axios。

到About.vue中,修改如下:

About.vue
<template>
<div class="about">
<h1>This is an about page</h1>
</div>
{{ user }}
</template>

<script>
export default {
data() {
return {
user: {}
}
},
mounted() {
this.$http.get("https://randomuser.me/api/")
.then((response) => {
this.user=response.data.results[0]
console.log(this.user)
})
}
}
</script>

<style>
@media (min-width: 1024px) {
.about {
min-height: 100vh;
display: flex;
align-items: center;
}
}
</style>

透過vue-axios取得資料

透過vue-axios取得資料