Vue.js & Django - axios post response status 200 but called catch error - api

i'm learning Vue.js and Django.
I want to post user info.
axios response status 200 code, but catch function is called.
If the response is successful, the login 'success dialog' is called , but the login 'fail dialog' is also called.
this image is console log.
enter image description here
please help me!
here is my code.
<script>
// LoginDialog.vue
import axios from "axios";
axios.defaults.xsrfCookieName = "csrftoken";
axios.defaults.xsrfHeaderName = "X-CSRFToken";
export default {
name: "LoginDialog",
components: {},
props: {
dialog: Boolean,
},
data() {
return {
showPassword: false,
dialogClose: {
success: false,
fail: false,
},
me: {},
};
},
setup() {},
created() {},
mounted() {},
unmounted() {},
computed: {
dialogOpen: {
get() {
return this.dialog;
},
set(val) {
this.$emit("close", val);
},
},
},
methods: {
save() {
console.log("save()...");
const postData = new FormData(document.getElementById("login-from"));
axios
.post("/api/login/", postData)
.then((res) => {
console.log("LOGIN POST RES", res);
// alert(`user ${res.data.username} login OK`);
this.dialogClose.success = true;
this.this.me = res.data;
})
.catch((err) => {
console.log("LOGIN POST ERR.RESPONSE", err.response);
this.dialogClose.fail = true;
// alert("login FAIL");
});
},
},
};
</script>
// LoginDialog.vue
<template>
<div>
<!-- 로그인 dialog -->
<v-dialog v-model="dialogOpen" max-width="500">
<v-card width="800" class="mx-auto mt-5">
<v-toolbar color="primary" dark flat>
<v-toolbar-title class="pb-0">
<h2>Login</h2>
</v-toolbar-title>
</v-toolbar>
<v-card-text>
<v-form id="login-from" ref="loginForm">
<v-text-field
label="Username"
name="username"
prepend-icon="mdi-account-circle"
></v-text-field>
<v-text-field
:type="showPassword ? 'text' : 'password'"
label="Password"
name="password"
prepend-icon="mdi-lock"
:append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
#click:append="showPassword = !showPassword"
autocomplete="on"
></v-text-field>
</v-form>
</v-card-text>
<v-divider></v-divider>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
text
color="grey"
center
#click="(dialogOpen = false), $refs.loginForm.reset()"
>Cancel</v-btn
>
<v-btn color="success" center #click="dialogOpen = false"
>Register</v-btn
>
<v-btn color="info" center #click="save()">Login</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<!-- login success 팝업창 -->
<v-dialog v-model="dialogClose.success" max-width="290">
<v-card>
<v-card-title class="text-h5"> Login Success! </v-card-title>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="green darken-1"
text
#click="dialogClose.success = false"
>
Close
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<!-- login fail 팝업창 -->
<v-dialog v-model="dialogClose.fail" max-width="290">
<v-card>
<v-card-title class="text-h5"> Login Fail! </v-card-title>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="green darken-1" text #click="dialogClose.fail = false">
Close
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>

So the Axios call goes well, but after that, in the .then block an error is thrown and caught by the .catch block. This is also why the err.response is empty, because that is an error object of Axios. If you log the err instead of err.response you might see the actual error (as Akzhol Kadylbek suggested in his comment).
Looking at your code, I presume that error comes from this line:
this.this.me = res.data;
/// change to this.me = res.data;
The double this. looks like a typo.
Hope this helps.

Related

How do I capture the value of the prop in the text field?

I have a prop and currently am able to get the data of the prop, Am trying a way to capture the item of the prop when saving the form.
Is there a way where i can take the value and pass if in a hidden text-area and bind the data to the vmodel?
Any help I appreciate.
<v-dialog v-model="dialog" persistent max-width="800">
<template v-slot:activator="{ on }">
<v-btn dark v-on="on" color="primary" round> Make payment </v-btn>
</template>
<v-card>
<v-card-title class="headline primary">
<span class="white--text">Add a new Doctor Payment Record {{ queueId }}</span>
<v-btn icon dark #click.native="dialog = false" absolute right>
<v-icon>mdi-close</v-icon>
</v-btn>
</v-card-title>
<v-card-text>
<users-search
:leave-selected="true"
idOnly
label="Select Doctor"
#results="setDoctor"
>
</users-search>
<div class="row px-3">
<v-autocomplete
class="px-3 col-sm-8"
v-model="expense.bank"
v-if="banks.data"
:items="banks.data"
outline
chips
label="Select bank"
item-text="name"
item-value="id"
>
</v-autocomplete>
<v-text-field
class="px-3 col-sm-8"
outline
flat
v-model="expense.amount"
type="number"
#input="expense.percentage()"
required
label="Amount *"
persistent-hint
/>
</div>
<v-text-field
class="px-3"
outline
flat
v-model="expense.total_paid"
required
label="amount paid"
persistent-hint
/>
<v-text-field
class="px-3"
outline
flat
:value="setQueue"
v-model="expense.queueId"
required
:label=queueId
persistent-hint
/>
<v-alert :value="true" type="error" v-if="errors.any()">
<div v-html="errors.display()"></div>
</v-alert>
<v-layout row wrap>
<v-flex xs12>
<v-btn
color="success"
:loading="saveLoader"
#click="recordExpense()"
>save</v-btn
>
</v-flex>
</v-layout>
</v-card-text>
</v-card>
</v-dialog>
</template>
<script>
import NewUser from "#finance/libs/users/NewUser";
import {mapActions, mapGetters} from "vuex";
export default {
props: [
'queueId'
],
data: () => ({
dialog: false,
expense: new NewUser(),
saveLoader: false,
}),
computed: {
...mapGetters({
banks: "getBanks",
}),
balance: function () {
return parseFloat(10);
},
submitted() {
return this.expense.form.submitted;
},
contaminated() {
return this.expense.form.errorDetected;
},
errors() {
return this.expense.form.errors;
},
},
watch: {
submitted(v) {
if (v) {
this.saveLoader = false;
}
},
contaminated() {
this.saveLoader = false;
},
},
methods: {
...mapActions({
fetchBanks: "setBanks",
}),
setDoctor(user) {
this.expense.doctor_id = user.id;
},
setQueue(){
console.log(this.queueId);
this.expense.queueId = this.queueId;
},
async recordExpense() {
this.saveLoader = true;
let response = await this.expense.saveExpense();
this.saveLoader = false;
if (response) {
this.dialog = false;
this.$emit("expenseCreated");
}
},
},
mounted() {
this.fetchBanks();
}
};
</script>
The prop queueId i also want to store it along with the user information from the form.
Try this one, it should work:
<template>
<textarea v-model="hiddenValue" :style="{ display: 'none' }"></textarea>
</template>
<script>
export default {
props: [ 'queueId' ],
data() {
return {
hiddenValue: this.queueId
}
}
}
</script>
In case you will no need the prop to be modified, please bind the texarea value to the prop directly:
<textarea hidden v-model="queueId" :style="{ display: 'none' }></textarea>

Vuetify reset form after submitting

I am using a form inside dialog using vuetify.
Imported the component in page like this -
<template>
<div>
<topicForm :dataRow="dataRow" v-model="dialog" />
</div>
</template>
methods: {
openDialog(item = {}) {
this.dataRow = item;
this.dialog = true;
},
}
Dialog form code -->
<template>
<div>
<v-dialog v-model="value" max-width="500px" #click:outside="close">
<v-card outlined class="pt-5">
<v-form ref="form" class="px-3">
<v-card-text class="pt-5">
<v-row no-gutters>
<v-text-field
required
outlined
label=" Name"
v-model="data.name"
:rules="[rules.required]"
></v-text-field>
</v-row>
<v-row no-gutters>
<v-textarea
required
outlined
label=" Description"
v-model="data.description"
></v-textarea>
</v-row>
</v-card-text>
</v-form>
<v-divider> </v-divider>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
large
dark
outlined
color="success"
#click="save"
class="ma-3"
>
Save
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>
props: [
"dataRow",
"value",
// ----------------------
],
methods: {
save() {
if (this.$refs.form.validate()) {
this.$root
.$confirm("Are you sure you want to save?")
.then((confirm) => {
if (confirm) {
this.ADD_TOPIC_DATA(this.data)
.then((data) => {
this.FETCH_TOPIC_DATA();
this.$refs.form.reset();
this.$refs.form.resetValidation();
this.close();
})
.catch((err) => {
console.log(err)
});
}
});
}
},
close() {
this.$emit("input", false);
},
}
watch: {
dataRow(val) {
this.data = { ...val };
},
},
Problem I am having is after adding a data, then if I try to add again by opening the dialog, the required field shows validation error, which is name here!
Image of that -->
Searched in stackoverflow. Found that should use this.$refs.form.reset(). Used that in save method without success. Also used this.$refs.form.resetValidation(), but don't work.
Any suggestion?
Thanks in advance.
The problem here is you're assigning new value to dataRow when opening the dialog which triggers validation inside the dialog. You could also use lazy-validation prop which allows you to only manually trigger the validation.

How to programatically close a Veutify dialog

Hello everyone i was searching on the vuetify documentation a function or something like that to close a form dialog just after getting the axios response with the status 200 ..
i don't if there's a way to get a dialog instance and use a close() method on it like the bootstrap modals
here's my code :
template code
<template>
<v-dialog justify-center max-width="500px">
<template v-slot:activator="{on}">
<v-icon
small
v-on="on"
>
mdi-pencil
</v-icon>
</template>
<v-card>
<form #submit.prevent="submit">
<v-card-text>
<v-text-field
v-model="name"
label="Name"
required
></v-text-field>
<v-text-field
v-model="email"
label="E-mail"
required
></v-text-field>
<v-text-field
v-model="password"
label="password"
required>
</v-text-field>
</v-card-text>
<v-card-actions>
<v-btn
color="blue darken-1"
text
>close</v-btn>
<v-btn
color="blue darke-1"
text
type="submit"
>apply</v-btn>
</v-card-actions>
</form>
</v-card>
</v-dialog>
</template>
and here's the script
<script>
export default {
data () {
return {
name: '',
email: '',
password: ''
}
},
methods: {
submit() {
let Data = new FormData()
Data.append('name', this.name)
Data.append('email', this.email)
Data.append('password', this.password)
axios.post('http://stage.test/admin/users', Data)
.then(Response => {
if (Response.status === 200) {
}
})
}
},
}
</script>
Try to bind dialog component to a data property called open as follows :
<template>
<v-dialog v-model="open" justify-center max-width="500px">
<template v-slot:activator="{on}">
<v-icon
small
v-on="on"
>
mdi-pencil
</v-icon>
.....
then in then callback assign false to this.open
<script>
export default {
data () {
return {
open:false,
name: '',
email: '',
password: ''
}
},
methods: {
submit() {
let Data = new FormData()
Data.append('name', this.name)
Data.append('email', this.email)
Data.append('password', this.password)
axios.post('http://stage.test/admin/users', Data)
.then(Response => {
if (Response.status === 200) {
this.open=false
}
})
}
},
}
</script>

Vue, error [vuex] do not mutate vuex store state outside mutation handlers

Here is original code. Very simple, sign in form. We have Email field, password. It takes this parameters and on clicking submit button it checks the user and writes his user.uid into Vuex. But I'm getting error which is listed above in title. I did research and it looks like it's a common issue in Vuex, due to those fields at some point updating Vuex store 'on a fly' which is false in my case, cause it only updates Vuex store when you press a submit button. Anyhow decided corrected to be look like this and still have no luck
original code
<template>
<div class="form__inner">
<div class="overlay" #click="$store.commit('logReg/logIn')"></div>
<v-container
fill-height
fluid>
<v-row
align="center"
justify="center">
<v-col cols="2">
<v-card>
<v-card-title>
Log in
</v-card-title>
<v-card-text>
<v-text-field placeholder="Email"
v-model="logIn"/>
<v-text-field placeholder="Password"
v-model="password"/>
</v-card-text>
<v-card-actions>
<v-btn color="success"
class="mx-auto"
#click="signIn">Log me in</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
</v-container>
</div>
</template>
<script>
export default {
data(){
return {
logIn: '',
password: ''
}
},
methods: {
async signIn(){
let res = await this.$fireAuth.signInWithEmailAndPassword(this.logIn, this.password);
this.$store.commit('userState', res);
}
}
}
</script>
my vuex
export const state = () => ({
user: null
})
export const mutations = {
userState(state, authUser){
state.user = authUser;
}
}
my try to fix issue which still had no luck, gives same error
<template>
<div class="form__inner">
<div class="overlay" #click="$store.commit('logReg/logIn')"></div>
<v-container
fill-height
fluid>
<v-row
align="center"
justify="center">
<v-col cols="2">
<v-card>
<v-card-title>
Log in
</v-card-title>
<v-card-text>
<v-text-field placeholder="Email"
v-model="logIn"/>
<v-text-field placeholder="Password"
v-model="password"/>
</v-card-text>
<v-card-actions>
<v-btn color="success"
class="mx-auto"
#click="signIn">Log me in</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
</v-container>
</div>
</template>
<script>
export default {
data(){
return {
logIn: '',
password: ''
}
},
computed: {
logg: {
get(){
return this.logIn;
},
set(val){
this.logIn = val;
}
},
pass: {
get(){
return this.password;
},
set(val){
this.password = val;
}
}
},
methods: {
async signIn(){
let res = await this.$fireAuth.signInWithEmailAndPassword(this.logg, this.pass);
this.$store.commit('userState', res);
}
}
}
</script>
You have to use mutations like this:
<script>
import {mapMutations} from 'vuex';
export default {
data(){
return {
logIn: '',
password: ''
}
},
methods: {
...mapMutations({
userState: 'userState'
}),
async signIn(){
let res = await this.$fireAuth.signInWithEmailAndPassword(this.logIn,this.password);
this.userState(res);
}
}
}
</script>

How do I open and close v-dialog from a component under its parent? Use Vuex?

I need to open a CRUD dialog from a data table component. Both the dialog and data table share the same parent. The data table is reusable but the CRUD dialog is not.
The use case seems very common. An admin page contains a table of data, each row containing an edit button that opens edit dialog.
I've attempted using Vuex below - however this error occurs:
[Vue warn]: Error in v-on handler: "TypeError: Cannot read property 'showUserModal' of undefined"
found in
---> <VBtn>
<VSimpleTable>
<VData>
<VDataTable>
<DataTable> at src/components/DataTable.vue
<Settings> at src/views/Settings.vue
<VContent>
<VApp>
<App> at src/App.vue
<Root>
Why is the imported mutator not available and is this a good approach to achieving the common functionality?
I arrived at my current solution using these 2 approaches
https://markus.oberlehner.net/blog/building-a-modal-dialog-with-vue-and-vuex/
https://forum.vuejs.org/t/how-to-trigger-a-modal-component-from-vuex-store/27243/9
UserAdmin.vue
<template>
<v-container fluid >
<DataTable v-bind:rows="allUsers" v-bind:headers="headers" />
<EditUser />
</v-container>
</template>
<script>
import { mapGetters, mapActions } from "vuex";
import DataTable from '../components/DataTable';
import EditUser from '../modals/EditUser';
export default {
name: 'UserAdmin',
methods: {
...mapActions(["getUsers"])
},
computed: mapGetters(["allUsers"]),
components: {
DataTable, EditUser
},
data(){
return {
headers: [
{ text: 'Name', value: 'name' },
{ text: 'Username', value: 'email' },
{ text: 'Administrator', value: 'admin' },
{ text: "", value: "controls", sortable: false}
]
}
},
created(){
this.getUsers();
}
}
</script>
DataTable.vue
<template>
<v-data-table
:headers="headers"
:items="rows"
:items-per-page="5"
class="elevation-1"
>
<!-- https://stackoverflow.com/questions/59081299/vuetify-insert-action-button-in-data-table-and-get-row-data -->
<template v-slot:item.controls="props">
<v-btn class="my-2" fab dark x-small color="blue" #click="onButtonClick(props.item.email)">
<v-icon dark>mdi-pencil</v-icon>
</v-btn>
</template>
</v-data-table>
</template>
<script>
import { mapMutations } from "vuex";
export default {
name: "DataTable",
props:["headers", "rows"],
methods: {
...mapMutations(["toggleUserModal"]),
onButtonClick: function(email) {
console.log("clicked: " + email)
this.toggleUserModal();
}
}
}
</script>
EditUser.vue
<template>
<v-row justify="center">
<v-dialog v-model="dialog" persistent max-width="600px" v-show='showUserModal'>
<v-card>
<v-card-title>
<span class="headline">User Profile</span>
</v-card-title>
<v-card-text>
<v-container>
<v-row>
<v-col cols="12" sm="6" md="4">
<v-text-field label="Legal first name*" required></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field label="Legal middle name" hint="example of helper text only on focus"></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field
label="Legal last name*"
hint="example of persistent helper text"
persistent-hint
required
></v-text-field>
</v-col>
<v-col cols="12">
<v-text-field label="Email*" required></v-text-field>
</v-col>
<v-col cols="12">
<v-text-field label="Password*" type="password" required></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-select
:items="['0-17', '18-29', '30-54', '54+']"
label="Age*"
required
></v-select>
</v-col>
<v-col cols="12" sm="6">
<v-autocomplete
:items="['Skiing', 'Ice hockey', 'Soccer', 'Basketball', 'Hockey', 'Reading', 'Writing', 'Coding', 'Basejump']"
label="Interests"
multiple
></v-autocomplete>
</v-col>
</v-row>
</v-container>
<small>*indicates required field</small>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" text #click="dialog = false">Close</v-btn>
<v-btn color="blue darken-1" text #click="dialog = false">Save</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-row>
</template>
<script>
export default {
data: () => ({
dialog: false,
}),
computed: {
showUserModal(){
return this.$store.state.showUserModal
}
}
}
</script>
modals.js
const state = {
showUserModal: false
}
const mutations = {
toggleUserModal: () => (this.showUserModal = !this.showUserModal)
}
const getters = {
showUserModal: state => {
return state.showUserModal
}
}
export default {
state,
getters,
mutations
}
New code based on #Anatoly suggestions - everything works except the events emitted from the dialog, ex: onEditUserConfirmed are not picked up in the parent component.
ModalComponent
<template>
<v-row justify="center">
<v-dialog v-model="visible" persistent max-width="600px">
<v-card v-if="user">
<v-card-title>
<span class="headline">User Profile</span>
</v-card-title>
<v-card-text>
<v-container>
<v-row>
<v-col cols="12" sm="6" md="4">
<v-text-field v-model="user.name" label="Legal first name*" required></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field label="Legal middle name" hint="example of helper text only on focus"></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field
label="Legal last name*"
hint="example of persistent helper text"
persistent-hint
required
></v-text-field>
</v-col>
<v-col cols="12">
<v-text-field label="Email*" required></v-text-field>
</v-col>
<v-col cols="12">
<v-text-field label="Password*" type="password" required></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-select :items="['0-17', '18-29', '30-54', '54+']" label="Age*" required></v-select>
</v-col>
<v-col cols="12" sm="6">
<v-autocomplete
:items="['Skiing', 'Ice hockey', 'Soccer', 'Basketball', 'Hockey', 'Reading', 'Writing', 'Coding', 'Basejump']"
label="Interests"
multiple
></v-autocomplete>
</v-col>
</v-row>
</v-container>
<small>*indicates required field</small>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" text #click="onCancel">Close</v-btn>
<v-btn color="blue darken-1" text #click="onSave">Save</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-row>
</template>
<script>
export default {
name: "EditUser",
props: {
user: Object,
visible: {
type: Boolean,
default: false
}
},
methods: {
onSave() {
console.log('save button gets here...')
this.$emit("onEditUserConfirmed", this.user);
},
onCancel() {
console.log('cancel button gets here...')
this.$emit("onEditUserCancelled");
}
}
};
</script>
Parent Component
<template>
<v-container fluid>
<v-data-table :headers="headers" :items="allUsers" :items-per-page="5" class="elevation-1">
<!-- https://stackoverflow.com/questions/59081299/vuetify-insert-action-button-in-data-table-and-get-row-data -->
<template v-slot:item.controls="props">
<v-btn class="my-2" fab dark x-small color="blue" #click="onEditClick(props.item)">
<v-icon dark>mdi-pencil</v-icon>
</v-btn>
</template>
</v-data-table>
<EditUser
:user="user"
:visible="isDialogVisible"
#confirmed="onEditUserConfirmed"
#cancelled="onEditUserCancelled"
/>
</v-container>
</template>
<script>
import { mapGetters, mapActions } from "vuex";
import EditUser from "../modals/EditUser";
export default {
name: "Settings",
data() {
return {
user: null,
isDialogVisible: false,
headers: [
{ text: "Name", value: "name" },
{ text: "Username", value: "email" },
{ text: "Administrator", value: "admin" },
{ text: "", value: "controls", sortable: false }
]
};
},
methods: {
...mapActions(["getUsers"]),
onEditClick: function(user) {
console.log('Editing user: ' + user.email)
this.user = user;
this.isDialogVisible = true;
},
onEditUserConfirmed(user) {
console.log('Saving user: ' + user.email)
this.isDialogVisible = false;
},
onEditUserCancelled () {
this.isDialogVisible = false;
}
},
computed: mapGetters(["allUsers"]),
components: {
EditUser
},
created() {
this.getUsers();
}
};
</script>
I would not recommend using the state for this task. since it not a very complex scenarios. you should use props and events for handling this kind of scenario
just modify the code a bit.
DataTable.vue
<script>
methods: {
onButtonClick: function(email) {
console.log("clicked: " + email)
this.$emit('openDialog') // or use any name here
}
}
</script>
UserAdmin.vue
<template>
<v-container fluid >
<!-- Listen to the event that you are emitting from DataTable.vue -->
<DataTable :rows="allUsers" :headers="headers" #showDialog="editUser = true" />
<!-- Pass that variable as a Prop -->
<EditUser :showDialog="editUser" />
</v-container>
</template>
<script>
....
data: () => ({
headers: [
{ text: 'Name', value: 'name' },
{ text: 'Username', value: 'email' },
{ text: 'Administrator', value: 'admin' },
{ text: "", value: "controls", sortable: false}
],
editUser: false, // a flag to keep the status of modal.
})
....
</script>
EditUser.vue
<script>
export default {
props: {
showDialog: {
type: Boolean,
default: false
}
},
data: () => ({
dialog: false,
}),
mounted() {
this.dialog = this.showDialog
},
watch: {
showDialog() {
if (this.showDialog)
this.dialog = true
}
}
}
</script>
I hope it should work, it worked for me in my scenario. I won't recommend using the Vuex store in this simple single level structure. Vuex should be used in case of some complex data structures where there are deep layers of components.
The code might have some syntax mistakes (do let me know). but i hope i just conveyed the concept
Use an event in a table component to inform a parent component you wish to edit a user (send a selected user in this event).
Catch the event in a parent component, write a user from the event to a prop in data section and pass this prop to a dialog component.
Use a prop to show/hide dialog from a parent component
Use an event to receive edited user after dialog confirmation.
Something like this:
Parent component
<DataTable v-bind:rows="allUsers" v-bind:headers="headers" #onEdit="onEditUser"/>
<EditUser :user="user" :visible="isDialogVisible" #confirmed="onEditUserConfirmed" #cancelled="onEditUserCancelled"/>
...
data: {
return {
// other data
user: null,
isDialogVisible : false
}
},
methods: {
onEditUser (user) {
this.user = user
this.isDialogVisible = true
},
onEditUserConfirmed (user) {
// hide a dialog
this.isDialogVisible = false
// save a user and refresh a table
},
onEditUserCancelled () {
// hide a dialog
this.isDialogVisible = false
}
}
Table component:
// better send a whole user object insteaf of just e-mail prop? It's up to you
#click="onButtonClick(props.item)"
...
methods: {
onButtonClick: function(user) {
this.$emit('onEdit', user)
}
}
Dialog component:
<v-dialog v-model="visible" ...
// render card only if user is passed
<v-card v-if="user">
<v-col cols="12" sm="6" md="4">
<v-text-field v-model="user.firstName" label="Legal first name*" required></v-text-field>
</v-col>
...
<v-btn color="blue darken-1" text #click="onCancel">Close</v-btn>
<v-btn color="blue darken-1" text #click="onSave">Save</v-btn>
...
export default {
props: {
user: {
type: Object
},
visible: {
type: Boolean,
default: false
}
},
...
methods: {
onSave() {
this.$emit('confirmed', this.user)
},
onCancel () {
this.$emit('cancelled')
}
}
}