【问题标题】:how to trigger two events with @click in vue.js如何在 vue.js 中使用 @click 触发两个事件
【发布时间】:2019-12-12 01:00:12
【问题描述】:

我正在使用 Vue.js、Vuetify 和 Firebase 构建一个任务管理器应用程序。单击“添加新注释”会打开一个 Vuetify 对话框,提示用户输入数据。单击保存关闭对话框,同时将输入的数据提交并呈现到屏幕上的任务卡。呈现的任务卡包括一个“查看/编辑”按钮,单击该按钮会打开第二个对话框,供用户查看和编辑数据。我的问题是编辑。我目前使用触发模式的@click 事件设置了“查看/编辑”按钮。我需要此查看/编辑@click 事件来触发将选定任务卡中的数据绑定到第二个对话框的函数,然后可以对其进行编辑。我试图通过在“查看/编辑”按钮中设置@click事件来实现这一点,如下所示:

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

...可以看到,@click事件包含“dialog = true”,用于切换Vuetify对话框,以及“editTodo(todo)”,触发绑定输入数据的editTodo函数到第二个对话框。这目前工作正常,但我的问题是我不清楚我是否应该真正为单击事件添加两个功能。我研究过的其他 Stack Overflow 帖子表明这不是一个好的做法。如果这是错误的,那么您建议如何配置“查看/编辑”按钮,以便打开第二个对话框也触发 editTodo 功能?我的完整组件如下。谢谢!

<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>

解决方案:

 <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
 },

【问题讨论】:

  • 将其包装在一个方法中并调用它。
  • 这行得通。谢谢!我没有想到可以将“dialogUpdate = true”添加到方法中。我将在上面添加我的解决方案。非常感谢!
  • 您应该发布自己的解决方案作为答案并接受它:)

标签: javascript firebase vue.js vuetify.js


【解决方案1】:

这就是解决方案。 dialogUpdate = true 应该包含在 editTodo() 函数中,以及用于将输入数据绑定到第二个对话框的代码。

<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
 },

【讨论】:

    猜你喜欢
    • 2018-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多