简体   繁体   中英

how to trigger two events with @click in vue.js

I am building a task manager app using Vue.js, Vuetify, and Firebase. Clicking "Add new note" opens a Vuetify dialog box which prompts the user to input data. Clicking save closes the dialog box while simultaneously submitting and rendering the inputted data to a task card on the screen. The rendered task card includes a "view/edit" button which, when clicked, opens a second dialog box for the user to view and edit data. My issue is with editing. I currently have the "view/edit" button set up with an @click event that triggers the modal. I need this view/edit @click event to also trigger a function that binds the data in a selected task card to the second dialog box, which can then be edited. I attempted to achieve this by setting up the @click event in the "view/edit" button like so:

<v-btn color="primary" dark @click.stop="dialogUpdate = true; editTodo(todo)">
   View/Edit
  </v-btn>

...as you can see, the @click event contains "dialog = true", which is used to toggle the Vuetify dialog box, and "editTodo(todo)", which triggers the editTodo function that binds the inputted data to the second dialog box. This currently works fine, but my issue is that I am not clear on whether or not I should actually be adding two functions to one click event. Other Stack Overflow posts that I have researched suggest that this is not a good practice. If this is wrong, then how would you recommend configuring the "view/edit" button so that opening the second dialog box also triggers editTodo function? My full component is below. Thank you!

<template>
  <div id="app" data-app>

    <v-layout justify-center>
      <v-btn color="primary" dark @click.stop="dialog = true">
        Add New Note
      </v-btn>

      <v-dialog v-model="dialog" max-width="290">
        <v-card color="#f9efaf">
          <v-form @submit.prevent="addTodo">
            <v-card-text>
              <textarea-autosize v-model="newTitle" :min-height="50" placeholder="add title"></textarea-autosize>
              <textarea-autosize v-model="newTodo" type="text" style="width: 100%" :min-height="100" placeholder="add note"></textarea-autosize>
            </v-card-text>
            <v-btn type="submit" color="green darken-1" text @click="dialog = false">
              Add
            </v-btn>
          </v-form>
          <v-card-actions>
            <v-spacer></v-spacer>
          </v-card-actions>
        </v-card>
      </v-dialog>

      <v-dialog v-model="dialogUpdate" max-width="290">
        <v-card color="#f9efaf">
          <v-form @submit.prevent="updateTodoText">
            <v-card-text>
              <textarea-autosize v-model="todoEditTitle" :min-height="50" placeholder="add title"></textarea-autosize>
              <textarea-autosize v-model="todoEditText" type="text" :min-height="100" placeholder="add note"></textarea-autosize>
            </v-card-text>
            <v-btn type="submit" color="green darken-1" text @click="dialogUpdate = false">
              Update
            </v-btn>
          </v-form>
          <v-card-actions>
            <v-spacer></v-spacer>
          </v-card-actions>
        </v-card>
      </v-dialog>
    </v-layout>

    <v-container>
      <v-flex md12 class="elevation-0">
       <v-layout wrap>
         <v-flex md3 v-for="todo in todos" :key="todo.id">
           <v-card color="#f9efaf" class="card-container">
             <textarea-autosize v-model="todo.title" class="todo-text" readonly style="width: 60%"></textarea-autosize>
             <textarea-autosize v-model="todo.text" class="todo-text" readonly></textarea-autosize>
              <v-btn @click="deleteTodo(todo.id)">Delete</v-btn>
              <v-btn color="primary" dark @click.stop="dialogUpdate = true; editTodo(todo)">
              View/Edit
            </v-btn>
          </v-card>
         </v-flex>
       </v-layout>
      </v-flex>
    </v-container>
  </div>
</template>

<script>
import { todosCollection } from './firebase';
import { mapState } from 'vuex'
export default {
  name: 'app',
  created() {
    this.getData();
  },
  data () {
    return {
      todos: [],
      newTitle: '',
      newTodo: '',
      currentlyEditing: null,
      todoEditTitle: '',
      todoEditText: '',
      dialog: false,
      dialogUpdate: false
    }
  },
  methods: {
    getData(){
      const todos = []
      todosCollection.orderBy('createdAt').get()
      .then(snapshot => {
        snapshot.forEach(doc => {
          let userData = doc.data()
          userData.id = doc.id
          todos.push(userData)
        })
        this.todos = todos
      })
    },
    addTodo() {
      todosCollection.add({
        title: this.newTitle,
        text: this.newTodo,
        createdAt: new Date()
      })
      .then(() => {
        this.newTitle = '',
        this.newTodo = ''
      })
    },
    deleteTodo(id) {
      todosCollection.doc(id).delete()
      .then(() => {
        console.log('Document successfully deleted')
      })
      .then(() => {
        this.getData()
      })
    },
    editTodo(todo) {
      this.currentlyEditing = todo.id
      this.todoEditText = todo.text
      this.todoEditTitle = todo.title
    },
    updateTodoText() {
      todosCollection.doc(this.currentlyEditing).update({
        text: this.todoEditText,
        title: this.todoEditTitle
      })
      .then(() => {
        this.getData()
      })
      .catch(function(error) {
        console.error("Error updating document text: ", error);
      });
      this.currentlyEditing = null;
      this.todoEditText = '';
      this.todoEditTitle = '';
    }
  }
}
</script>

<style>
body {
  margin: 0;
  padding: 0;
}
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #2c3e50;
  margin: 0;
  padding: 0;
}
.card-container {
  margin: 10px;
  padding: 10px;
}
</style>

SOLUTION:

 <v-btn color="primary" dark @click.stop="editTodo(todo)">
    View/Edit
 </v-btn>


 editTodo(todo) {
   this.dialogUpdate = true
   this.currentlyEditing = todo.id
   this.todoEditText = todo.text
   this.todoEditTitle = todo.title
 },

This is the solution. dialogUpdate = true is supposed to be wrapped inside the editTodo() function, along with code used to bind the inputted data to the second dialog box.

<v-btn color="primary" dark @click.stop="editTodo(todo)">
    View/Edit
 </v-btn>


 editTodo(todo) {
   this.dialogUpdate = true
   this.currentlyEditing = todo.id
   this.todoEditText = todo.text
   this.todoEditTitle = todo.title
 },

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM