118118 </v-container >
119119 <v-form ref =" form" v-model =" formValidation" >
120120 <v-text-field label =" Title" v-model =" getDemoPayload.title" :rules =" titleRules" clearable />
121- <v-text-field label =" Text" v-model =" getDemoPayload.text" clearable />
122- <v-text-field label =" Rating" v-model =" getDemoPayload.rating" />
123- <v-text-field label =" Email" v-model =" getDemoPayload.email" />
124- <v-text-field label =" Domain Name" v-model =" getDemoPayload.site" />
125- <v-btn v-throttled-click =" handleThrottledClickRendRequest" small >Send request</v-btn >
121+ <v-text-field label =" Text" v-model =" getDemoPayload.text" :rules =" textRules" clearable />
122+ <v-text-field label =" Rating" v-model =" getDemoPayload.rating" :rules =" ratingRules" />
123+ <v-text-field label =" Email" v-model =" getDemoPayload.email" :rules =" emailRules" />
124+ <v-text-field label =" Domain Name" v-model =" getDemoPayload.site" :rules =" siteRules" />
125+ <v-btn v-debounced-click:300 =" handleDebouncedClickRendRequest" :loading =" sendRequestLoading" small >Send request
126+ </v-btn >
126127 </v-form >
127128 </v-container >
128129 </div >
@@ -133,9 +134,17 @@ import Vue from 'vue'
133134import { vuetifyDemoApi } from ' @/requests/vuetify-demo'
134135// eslint-disable-next-line no-unused-vars
135136import { GetDemoPayload } from ' @/requests/vuetify-demo/payload/get-demo-payload'
137+ import validator from ' validator'
138+ // eslint-disable-next-line no-unused-vars
139+ import { VForm } from ' @/shims-tsx'
136140
137141export default Vue .extend ({
138142 name: ' VuetifyDemo' ,
143+ computed: {
144+ form (): VForm {
145+ return this .$refs .form as VForm
146+ }
147+ },
139148 data : () => ({
140149 colors: [' indigo' , ' warning' , ' pink darken-2' , ' red lighten-1' , ' deep-purple accent-4' ],
141150 slides: [' First' , ' Second' , ' Third' , ' Fourth' , ' Fifth' ],
@@ -150,9 +159,50 @@ export default Vue.extend({
150159 formValidation: false ,
151160 getDemoPayload: new GetDemoPayload (),
152161 titleRules: [
153- (v : string ) => !! v || ' Title is required' ,
154- (v : string ) => (v && (10 <= v .length || v .length <= 20 )) || ' Name mustn\' t less than 10 characters and more than 20 characters!'
155- ]
162+ (v : string ) => !! v || ' Title is required.' ,
163+ (v : string ) => {
164+ if (v && ! validator .isLength (v , 10 , 20 )) {
165+ return ' The length of title must not be less than 10 characters and not be more than 20 characters!'
166+ }
167+ return true
168+ }
169+ ],
170+ textRules: [
171+ (v : string ) => !! v || ' Test is required.' ,
172+ (v : string ) => {
173+ if (v && ! validator .contains (' hello' , v )) {
174+ return ' The text need to contain `hello`!'
175+ }
176+ return true
177+ }
178+ ],
179+ ratingRules: [
180+ (v : number ) => !! v || ' Rating is required.' ,
181+ (v : number ) => {
182+ if (v && (v < 0 || v > 10 )) {
183+ return ' The value range of rating should be [0, 10]!'
184+ }
185+ return true
186+ }
187+ ],
188+ emailRules: [
189+ (v : string ) => !! v || ' Email is required.' ,
190+ (v : string ) => {
191+ if (v && ! validator .isEmail (v )) {
192+ return ' Invalid email!'
193+ }
194+ return true
195+ }
196+ ],
197+ siteRules: [
198+ (v : string ) => {
199+ if (v && ! validator .isFQDN (v )) {
200+ return ' Invalid domain name!'
201+ }
202+ return true
203+ }
204+ ],
205+ sendRequestLoading: false
156206 }),
157207 mounted () {
158208 this .onResize ()
@@ -182,9 +232,19 @@ export default Vue.extend({
182232 handleDebouncedClickButton (event : Event ) {
183233 console .info (' handleDebouncedClickButton' , event )
184234 },
185- async handleThrottledClickRendRequest () {
235+ async handleDebouncedClickRendRequest (event : Event ) {
236+ console .info (' handleDebouncedClickRendRequest' , event )
237+ this .form .validate ()
238+ if (! this .formValidation ) {
239+ this .$toast .warning (' The form is incorrect!' )
240+ return
241+ }
242+ this .sendRequestLoading = true
186243 const response = await vuetifyDemoApi .getDemo (this .getDemoPayload )
187- console .info (' Response' , response )
244+ this .$toast .success (response .message )
245+ setTimeout (() => {
246+ this .sendRequestLoading = false
247+ }, 2000 )
188248 },
189249 onResize () {
190250 this .windowSize = { x: window .innerWidth , y: window .innerHeight }
0 commit comments