表單驗證補充 在課程中原本是用第二版的vee-validate,安裝與指令步驟  。npm uninstall vee-validate,將vee-validate給卸載。npm install vee-validate --save,來安裝新版的vee-validate套件。
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 27 28 29 30 31 ---main.js--- import Vue from 'vue' import axios from 'axios' import VueAxios from 'vue-axios' import Loading from 'vue-loading-overlay';  // 引入overlay元件 import 'vue-loading-overlay/dist/vue-loading.css';  // 引入overlay元件 import 'bootstrap' import App from './App' import router from './router' import './bus' import currencyFilter from './filters/currency' //import VeeValidate from 'vee-validate';    // 原本的vee-validate內容拿掉 //import zhTWValidate from 'vee-validate/dist/locale/zh_TW'  // 原本的vee-validate內容拿掉 import zhTW from 'vee-validate/dist/locale/zh_TW' import VueI18n from 'vue-i18n' Vue.use(VueAxios, axios) //Vue.use(VeeValidate);   // 原本的vee-validate內容拿掉 //VeeValidate.Validator.localize('zh_TW', zhTWValidate);   // 原本的vee-validate內容拿掉 Vue.config.productionTip = false Vue.component('Loading', Loading);  // 啟用overlay元件 Vue.filter('currency', currencyFilter);  // 啟用fiter元件 // Vue.use(VeeValidate, { //   events: 'input|blur', //這是為了讓使用者離開該欄位時觸發驗證 //   i18n, //   dictionary: { //     zhTW //   } // }) 
你可以看到,我們把引入檔案和創建vee-validate元件的內容給註解掉了。
step5.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ---main.js--- <!--引入元件--> import { ValidationObserver, ValidationProvider, extend, localize, configure } from 'vee-validate'; import TW from 'vee-validate/dist/locale/zh_TW.json' import * as rules from 'vee-validate/dist/rules'; <!--引入元件--> <!--元件規則--> Object.keys(rules).forEach((rule) => {   extend(rule, rules[rule]); }); localize('zh_TW', TW); Vue.component('ValidationObserver', ValidationObserver) Vue.component('ValidationProvider', ValidationProvider) configure({   classes: {     valid: 'is-valid',     invalid: 'is-invalid'   } }); <!--元件規則--> 
那小小解釋一下,引入的內容分別代表什麼意思
元件規則部分
在localize('zh_TW', TW)的部分,就套件繁體中文功能的部分。Vue.component('ValidationObserver', ValidationObserver)的部分,就代表input單一欄位驗證功能的部分。Vue.component('ValidationProvider', ValidationProvider)的部分,是代表整體form表單的驗證功能部分。
在configure中,就是className的設定檔。
step6.
1 2 3 4 5 6 7 8 9 10 11 <validation-provider rules="required|email" v-slot="{ errors, classes }"> 	<!-- 輸入框 --> 	<div class="form-group"> 		<label for="email">Email</label> 		<input id="email" type="email" name="email"  			class="form-control" v-model="form.user.email" :class="classes"> 		<!-- 錯誤訊息 --> 		<span class="invalid-feedback">{{ errors[0] }}</span> 	</div> 	 </validation-provider> 
a.你可以看到我們先用validation-provider元件將那些要驗證的內容給包起來。input的欄位中,記得要加入v-model的綁定效果喔。validation-provider標籤中,rules是代表它是吃什麼規則的,rules="required|email",代表該input欄位是必填的,v-slot="{errors}",是可以把外部的錯誤資訊導入到validation-provider標籤內,供裡面的元件使用,<span>{{ errors[0] }}</span> 裡面用的errors就是從取外部娶進來的資料。
加上以上的內容後,email欄位的驗證效果就可以正常運作囉~~~
step7.v-slot來增加。
1 2 3 4 5 6 7 8 9 10 11 <validation-provider rules="required|email" v-slot="{ errors, classes }"> 	<!-- 輸入框 --> 	<div class="form-group"> 		<label for="email">Email</label> 		<input id="email" type="email" name="email"  			class="form-control" v-model="form.user.email" :class="classes"> 		<!-- 錯誤訊息 --> 		<span class="invalid-feedback">{{ errors[0] }}</span> 	</div> 	 </validation-provider> 
你可以看到我們在v-slot中加入了classes並在input欄位中透過v-bind來動態的綁定這個classes,span套上了bootstrap的invalid-feedback的樣式,來讓它的內容呈現紅色的字樣。
step8.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <validation-observer  class="col-md-6" v-slot="{ invalid }"> 	<form> 		<validation-provider rules="required|email" v-slot="{ errors, classes }"> 			<!-- 輸入框 --> 			<div class="form-group"> 				<label for="email">Email</label> 				<input id="email" type="email" name="email"  					class="form-control" v-model="form.user.email" :class="classes"> 				<!-- 錯誤訊息 --> 				<span class="invalid-feedback">{{ errors[0] }}</span> 			</div> 			 		</validation-provider> 		<div class="text-right"> 			<button class="btn btn-danger" type="submit" @click.prevent="createOrder" :disabled="invalid">送出訂單</button> 		</div> 	</form> </validation-observer> 
你可以看到,我們直接用validation-observer標籤把form表單給包起來,並且在validation-observer的標籤上有一個v-slot可以將invalid的disabled屬性作綁定,如果表單內的格式有誤,這個按鈕式沒有辦法被按下去的。
按照以上的方式,我們就可以順利的使用新版的vee-validate的驗證功能囉~~
step9.
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 <template> <validation-observer  class="col-md-6" v-slot="{ invalid, handleSubmit  }"> 	<form @submit.prevent="handleSubmit(submitForm)"> 		<validation-provider rules="required" v-slot="{ errors, classes }"> 			<!-- 輸入框 --> 			<div class="form-group"> 				<label for="useraddress">收件人地址</label> 				<input id="useraddress" type="text" name="地址"  					class="form-control" v-model="form.user.address" :class="classes" placeholder="請輸入地址" > 				<!-- 錯誤訊息 --> 				<span class="invalid-feedback">{{ errors[0] }}</span> 			</div> 		</validation-provider> 		<validation-provider v-slot="{ errors, classes }"> 			<!-- 輸入框 --> 			<div class="form-group"> 				<label for="comment">留言</label> 				<textarea name="" id="comment" class="form-control" cols="30" rows="10" v-model="form.message"></textarea> 			</div> 		</validation-provider> 		 		<div class="text-right"> 			<button class="btn btn-danger" :disabled="invalid">送出訂單</button> 		</div> 	 		 	</form> </validation-observer> </template> <script> 	methods:{ 		submitForm() { 			const vm = this;  			const order = vm.form; 			const api = `${process.env.APIPATH}/api/${process.env.CUSTOMPATH}/order`; 			vm.isLoading = true; 			this.$http.post(api,{data:order}).then((response) => {   				console.log('訂單已建立', response); 			}) 			console.log('送出表單'); 			vm.isLoading = false; 		} 	} </script> 
你可以看到在validation-observer標籤上是綁定了handleSubmit事件。form標籤上@submit.prevent="handleSubmit(submitForm)"綁定了這個submitForm事件。
結帳頁面製作 step1.取得訂單列表的api  。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ---index.js-- import CustomerCheckOut from '@/components/pages/CustomerCheckOut' // 引入customer_CheckOut元件 {       path: '/',       name: 'DashBoard',       component: DashBoard,       children:[         {           path:'customer_order',           name: 'CustomerOrder',           component: CustomerOrder,         },         {           path:'customer_CheckOut/:orderId',   // 新增這個customer_CheckOut的元件和路徑           name: 'CustomerCheckOut',           component: CustomerCheckOut,         },       ] }, 
以上,我們就引入了customer_CheckOut這個元件的名稱和路徑。
step2.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 methods:{ 	submitForm() { 		const vm = this;  		const order = vm.form; 		const api = `${process.env.APIPATH}/api/${process.env.CUSTOMPATH}/order`; 		vm.isLoading = true; 		this.$http.post(api,{data:order}).then((response) => {   			console.log('response', response); 			 console.log('response1', response.data.success); 			if(response.data.success){ 				console.log('訂單已建立'); 				vm.$router.push(`/customer_CheckOut/${response.data.orderId}`);  // 跳轉頁面 			} 		}) 		vm.isLoading = false; 	} } 
在我們成功送出訂單之後,會直接用push的方式來跳轉到取得訂單頁面。
step3.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 ---customer_CheckOut.vue--- <script>     export default{         data(){            return{                orderId:'',            }         },         created(){             this.orderId = this.$route.params.orderId;  // 取得該router的id             console.log(this.orderId);         }     } </script> 
這邊你要特別注意,在this.$route.params.orderId的orderId的變數名稱。
1 2 3 4 5 6 ---index.js--- {   path:'customer_CheckOut/:orderId',  //都要叫orderId   name: 'CustomerCheckOut',   component: CustomerCheckOut, }, 
這邊你要特別注意,在this.$route.params.orderId的orderId的變數名稱要跟你在index.js檔案裡面orderId變數名稱一樣,
step4.
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 27 28 29 30 <script>     export default{         data(){            return{                orderId:'',                order:{                    user:{                        email:''                    }                }            }         },         methods:{             getList(){                 const vm = this;                 const api = `${process.env.APIPATH}/api/${process.env.CUSTOMPATH}/order/${vm.orderId}`;                                  this.$http.get(api).then((response) => {                     vm.order = response.data.order;                   })             }         },         created(){             this.orderId = this.$route.params.orderId;             console.log(this.orderId);             this.getList();         }     } </script> 
以上的內容你就可以看到我們將後端的data.order裡面的資料取進來放在order物件中,
step5.
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 27 28 <form class="col-md-6" @submit.prevent="payOrder"> 	<table class="table"> 		<thead> 			<th>品名</th> 			<th>數量</th> 			<th>單價</th> 		</thead> 	</table> 	<div class="text-right" v-if="order.is_paid === false"> 	<button class="btn btn-danger">確認付款去</button> 	</div> </form> <script> 	methods:{ 		payOrder(){ 			const vm = this; 			const api = `${process.env.APIPATH}/api/${process.env.CUSTOMPATH}/pay/${vm.orderId}`; 			vm.isLoading = true; 			this.$http.post(api).then((response) => { 			   vm.getList();  			   vm.isLoading = false; 			}) 		} 	} </script> 
你可以看到我們為提交表單新增了一個payOrder的方法,並在提交完成後重新讀取一次該表單的內容,
以上就完成付款的功能囉。
最終作業說明 目前我們專案都是用npm run dev的方式來運行專案,但是,我們不可能直接將這種形式的檔案給別人看。npm run build。
小插曲- npm run build沒有辦法呈現頁面 當我用live server打開dist資料夾中的index.html後,沒有畫面,
分享另一個小地方,http://landy510.github.io  底下,而是在http://landy510.github.io/Vue-testing底下,