Vue alerts and pop-ups will only show once

Utilizing vue ui to create a new project with Babel and Lint, I integrated dependencies vuetify, vuetify-loader, and vue-bootstrap. My goal was to have a simple 'open dialog' button that would reveal a dialog defined in a separate component file. The dialog appeared without any issues or warnings, but upon closing it (either by clicking elsewhere or on one of the buttons), I received a warning stating "Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders." Subsequently, clicking the button again had no effect, despite seeing "JAAA" in the console. Here is the code:

HelloWorld.vue

<template>
  <div class="hello">

    <v-btn @click="openDialog" class="btn btn-info">Open dialog</v-btn>
                <Dialog :showDialog="showDialog"></Dialog>
  </div>
</template>

<script>
  import Dialog from "./Dialog";
  export default {
    name: 'HelloWorld',
    components: {
      Dialog
    },
    props: {
      msg: String
    },
    data() {
      return {
              showDialog: false
          }
      },
      methods: {
        openDialog() {
          this.showDialog = true
          window.console.log('JAAA')
        }
      }
  }
</script>

Dialog.vue

<template>
  <div>
    <v-dialog v-model="showDialog" width="500">
      <v-card>
        <v-card-title class="headline grey lighten-2" primary-title>
          Remark
        </v-card-title>
        <v-card-text>
          Remark: <input type="text">
        </v-card-text>
        <v-divider></v-divider>
        <v-card-actions>
          <div class="flex-grow-1"></div>
          <v-btn color="primary" text @click="hideDialog">
            Done
          </v-btn>
          <v-btn color="primary" text @click="hideDialog">
            Cancel
          </v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
  </div>
</template>

<script>
    export default {
        name: "Dialog",
        props: ['showDialog'],
        methods: {
          hideDialog() {
            this.showDialog = false;
          }
        }
    }
</script>

Answer №1

A best practice is to avoid directly modifying props within a component because any changes won't be reflected in the parent component.

Instead, you can convert your dialog component to utilize a v-model along with a computed property in the child component to emit updates to the parent component, ensuring it stays aware of the updated value.

HelloWorld.vue

<template>
  <div class="hello">
    <v-btn @click="openDialog" class="btn btn-info">Open dialog</v-btn>
    <Dialog v-model="showDialog"></Dialog>
  </div>
</template>

<script>
import Dialog from "./Dialog";
export default {
  name: 'HelloWorld',
  components: {
    Dialog
  },
  props: {
    msg: String
  },
  data() {
    return {
      showDialog: false
    }
  },
  methods: {
    openDialog() {
      this.showDialog = true
      window.console.log('JAAA')
    }
  }
}
</script>

Dialog.vue

<template>
  <div>
    <v-dialog v-model="displayDialog" width="500">
      <v-card>
        <v-card-title class="headline grey lighten-2" primary-title>
          Remark
        </v-card-title>
        <v-card-text>
          Remark: <input type="text">
        </v-card-text>
        <v-divider></v-divider>
        <v-card-actions>
          <div class="flex-grow-1"></div>
          <v-btn color="primary" text @click="hideDialog">
            Done
          </v-btn>
          <v-btn color="primary" text @click="hideDialog">
            Cancel
          </v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
  </div>
</template>

<script>
export default {
  name: "Dialog",
  props: {
    value: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    displayDialog: {
      get() {
        // returns the value of your prop
        return this.value 
      },
      set(newValue) {
        // Using v-model listens to input event, emitting 'input' with a new value updates the model
        this.$emit('input', newValue)
      }
    };
  },
  Methods: {
    hideDialog() {
      this.displayDialog = false;
    }
  }
}
</script>

Answer №2

Modifying the value in the child component will not affect the parent as props data flows only when the child component is created and any changes made in the child component do not reflect back to the parent. The state is not shared between them, so from then on, only the updated hook in the dialog box is called.

To implement these modifications in the Dialog.vue component

<template>
  <div>
    <v-dialog v-model="displayDialog" width="500">
      <v-card>
        <v-card-title class="headline grey lighten-2" primary-title>
          Remark
        </v-card-title>
        <v-card-text>
          Remark: <input type="text">
        </v-card-text>
        <v-divider></v-divider>
        <v-card-actions>
          <div class="flex-grow-1"></div>
          <v-btn color="primary" text @click="hideDialog">
            Done
          </v-btn>
          <v-btn color="primary" text @click="hideDialog">
            Cancel
          </v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
  </div>
</template>

<script>
    export default {
        name: "Dialog",
        props: {
          showDialog: {
            type: Boolean,
          }
        },
        data() {
          return {
            displayDialog: false,
          };
        },
        methods: {
          hideDialog() {
            this.displayDialog = false;
          }
        },
       watch: {
          showDialog(val) {
             this.displayDialog  = val;
          }
       }
    }
</script>

Answer №3

I found a solution that worked for me: To close the dialog, you simply need to emit an event to the parent component and update the dialog property value (i.e., close the dialog from the parent instead of the child)

      <div class="hello">
            <Dialog v-model="showDialog" @closeDialog="showDialog=false"> </Dialog>
      </div>

The dialog component looks like this:

  <v-dialog v-model="displayDialog" width="500"gt;
      .....
        <v-card-actions>
          <div class="flex-grow-1"></div>
          <v-btn color="primary" text @click="$emit('closeDialog')">
            Done
          </v-btn>
          <v-btn color="primary" text @click="$emit('closeDialog')">
            Cancel
          </v-btn>
        </v-card-actions>
     ......
    </v-dialog>


  export default {
        name: "Dialog",
        props: {
          showDialog: {
            type: Boolean,
          }
        },
        data() {
          return {
            displayDialog:this.showDialog,
          };
        },

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having trouble assigning a value to the datapicker through the onchange event and the name attribute in the code below

const stateValues = { code: '', product: '', checked: 'false', jobCardNo: '', openDate: '', completionDate: '', serial: '', technicalNo: '', ...

Uninstalling Vue.js from a Rails application using webpack

After using the command line to install Vue.js, I'm now looking to uninstall it. Is there a way to revert the installation process? bundle exec rails webpacker:install:vue Any guidance on removing Vue.js would be greatly appreciated. ...

Excessive JSON formatting is consuming an excessive amount of storage space

As I work on developing a website that recommends locations to visit in NYC, I am facing an issue with saving JSON data in local storage. My goal is to allow users to add their own suggestions and eventually integrate MongoDB into the site. To build the si ...

What is the best way to showcase my React App.js in an HTML document?

Is there a way to display my React app file (App.Js) within my Index.html file? <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <link rel="icon" href="%PUBLIC_URL%/fav ...

A guide on breaking down a URL string containing parameters into an array with the help of JavaScript

I need help splitting a long string into an array with specific index structure like this: fname=bill&mname=&lname=jones&addr1=This%20House&... I am looking to have the array set up as shown below: myarray[0][0] = fname myarray[0][1] = b ...

How can we transfer parameters in JavaScript?

My vision may be a bit vague, but I'll try to explain it as best as I can. I want to implement multiple buttons that can toggle the visibility of a div (I have this functionality working already). Each button should carry two values (a number and a l ...

What is the best way to ensure that child elements within a container div are centered when scrolling left and right?

When attempting to handle the 'scroll' event, I noticed that the callback function only records the position of the div as the last position. I am looking for a way to determine if the div is in the center, which is my target. const slide = ...

A valid path is required in the form of a string when working with the HTTP module in Node.js

Currently, I'm working on an update checker that doesn't involve downloading the update. My main goal is to compare the version in the package.json file on GitHub with the one in my Electron app. However, when using this code, I encountered a "p ...

An issue arises with the Datatables destroy function

Utilizing datatables.js to generate a report table on my page with filters. However, when applying any of the filters, the data returned has varying column counts which prompts me to destroy and recreate the table. Unfortunately, an error message pops up ...

The error message "window is not defined" occurs when the external file 'signalr.min.js' is included

Updates OpenTest --version 1.2.2 ChromeDriver 85.0.4183.87 Whenever I attempt to add the necessary external javascript files, it results in the following errors: Caused by: java.lang.RuntimeException: Failed to evaluate JavaScript code at line number 1. ...

Challenges with form validation

Hello everyone, I'm a newbie to JS and struggling with my code. It seems like everything should work, but it just won't. The issue seems to be with the phone number form validation. I've written code that, in theory, should do the job, but ...

Success Notification in ASP.net MVC after Form Submission

I am looking to implement a success alert pop-up or message after the form is submitted and action is successful. In this scenario, I want to display "successfully add": Create Action : [HttpPost] [ValidateAntiForgeryToken] public ActionResult Cr ...

What is the best way to sort ISO DateTime objects that fall outside of a particular time frame?

I'm currently working on a project that involves a list of objects with properties for startTime and endTime, all in ISO format. Here's a snippet of the list: list = [ { startTime: '2022-06-26T10:00:00.000Z', endTime: '2022- ...

Executing a webservice method in an html page using javascript without the need to refresh the page

Is it possible to call a webservice from an index.html page using JavaScript? My webservice is located at "localhost/ws/service.asmx" and the specific web method I want to call is called HelloWorld. The index.html page contains an HTML submit button whic ...

Creating a compact array from a larger array in JavaScript

I am currently using the jquery.bracket library and I am looking to split a large array into pairs like ["'Team 1', 'Team 2'"],["'Team 3', 'Team 4'"] from var all= ["'Team 1', 'Team 2'","'T ...

In development, Next.js dynamic routes function correctly, but in production they are displaying a 404 error page

I am currently working on implementing dynamic routes in my Next.js project to render pages based on user input. I have set up a route that should display the page content along with the id extracted from the URL using the useRouter() hook. Everything is f ...

Create a unique bar chart plugin using Javascript/jQuery that allows users to drag and drop data

My current project involves developing a custom bar chart generator that must meet specific criteria: Input fields for entering data to display on the chart The ability to drag and resize bars once the chart is generated I've conducted research and ...

External JavaScript files cannot be used with Angular 2

I am attempting to integrate the twitter-bootstrap-wizard JavaScript library into my Angular 2 project, but I keep encountering the following error: WEBPACK_MODULE_1_jquery(...).bootstrapWizard is not a function I have created a new Angular app using a ...

Issues with sending an AJAX POST request to a PHP script

Hello, I am trying to send a variable from an AJAX JavaScript file to a PHP file. Here is what I have done so far: var request = createRequest(); var deletenode = node.id; window.alert("nodeid=" + deletenode); var vars = "deletenode ...

What is the best way to transfer information from my function to the data method?

I'm currently facing an issue with passing data from my API to the data method in Vue. data(){ return{ name:"" } }, methods: { getData(){ ...