Create Form Component with Validation (using vuelidate)
Edit components/PlaceForm.vue
<template> <div> <b-form ref="form" @submit.prevent="submit"> <b-form-group label="Name" label-for="input-name" invalid-feedback="Name is required" > <b-form-input :state="validateState($v.item.name)" id="input-name" v-model="$v.item.name.$model" ></b-form-input> </b-form-group> <b-button type="submit" variant="primary">Submit</b-button> </b-form> </div></template><script>import { validationMixin } from "vuelidate"import { required, minLength } from "vuelidate/lib/validators"export default { mixins: [validationMixin], props: ['item'], /* data() { item: { name: 'Desmond' }, }, */ validations: { item: { name: { required }, } }, methods: { validateState(item) { const { $dirty, $error } = item return $dirty ? !$error : null }, submit() { this.$v.item.$touch() if (this.$v.item.$anyError) return false return this.item } }}</script>
Usage: a table of items, each row have an edit button to show edit form as modal
<template> <div> <b-table striped hover :items="items" :fields="fields"> <template v-slot:cell(action)="data"> <b-button size="sm" variant="outline-primary" @click="showEditPlaceModel(data.index, data.item)">Edit</b-button>> </template> </b-table> <b-modal ref="editPlaceModal" title="Edit Place" @ok.prevent="submitEditPlace"> <place-form ref="editPlaceForm" :item="editPlace" /> </b-modal> </div></template><script>import Vue from 'vue'import PlaceForm from '~/components/PlaceForm.vue'export default { data() { return { fields: ['name', 'action'], items: [ { name: 'New York' }, { name: 'Tokyo' }, { name: 'Kuala Lumpur' } ], editPlace: null, editIndex: null } }, methods: { showEditPlaceModel(index, data) { // deep clone editPlace = JSON.parse(JSON.stringify(data)) // shallow clone // this.editPlace = Object.assign({}, data) this.editIndex = index this.$refs.editPlaceModal.show() }, submitEditPlace() { const data = this.$refs.editPlaceForm.submit() if (data) { // do something: save data? // reactive caveats // this.items[this.editIndex] = newData Vue.set(this.items, this.editIndex, data) this.$nextTick(() => { this.$refs.editPlaceModal.hide() }) } } }, components: { PlaceForm }}</script>