Vue.js 添加和编辑相同的表单

Vue.js same form for add and edit

我是 vue.js 的菜鸟,我正在尝试扩展一些已完成的教程。 现在已经和这三个小时战斗了,我很沮丧。仅供参考,我正在使用 firebase,但我不确定它在这里真的很重要。

所以,我有一个用于列出电影的 CRUD 应用程序(我告诉过你这是基本的!)。 页面顶部有一个表格,您可以在其中添加电影,下面有一个 table,其中列出了新的注册表。这很好用。

我在 table 的每一行中添加了编辑和删除按钮。删除功能有效。但是问题出在编辑功能上。

我想在初始表单上使用 v-if 来触发不同的方法(保存、编辑)并显示不同的按钮(添加、保存、取消)。

我不确定如何访问对象来执行此操作,我尝试了一些操作,但 v-if 显示对象未定义。

感谢您的阅读,有什么想问的请问

import './firebase' // this has my credententials and initializeApp
import Vue from 'vue'
import App from './App'
import VueFire from 'vuefire'

Vue.use(VueFire)
Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  template: '<App/>',
  components: { App }
})
<template>
  <div id="app" class="container">
    <div class="page-header">
      <h1>Vue Movies</h1>
    </div>
 
    <div class="panel panel-default">
      <div class="panel-heading">
        <h3>Add Movie</h3>
      </div>
 
      <div class="panel-body">

        <div v-if="!isEditing">
          <form id="form" class="form-inline" v-on:submit.prevent="addMovie">
            <div class="form-group">
              <label for="movieTitle">Title:</label>
              <input type="text" id="movieTitle" class="form-control" v-model="newMovie.title">
            </div>
            <div class="form-group">
              <label for="movieDirector">Director:</label>
              <input type="text" id="movieDirector" class="form-control" v-model="newMovie.director">
            </div>
            <div class="form-group">
              <label for="movieUrl">URL:</label>
              <input type="text" id="movieUrl" class="form-control" v-model="newMovie.url">
            </div>
            <input type="submit" class="btn btn-primary" value="Add Movie">
          </form>
        </div>

        <div v-else>
          <form id="form" class="form-inline" v-on:submit.prevent="saveEdit(movie)">
            <div class="form-group">
              <label for="movieTitle">Title:</label>
              <input type="text" id="movieTitle" class="form-control" v-model="movie.title">
            </div>
            <div class="form-group">
              <label for="movieDirector">Director:</label>
              <input type="text" id="movieDirector" class="form-control" v-model="movie.director">
            </div>
            <div class="form-group">
              <label for="movieUrl">URL:</label>
              <input type="text" id="movieUrl" class="form-control" v-model="movie.url">
            </div>
            <input type="submit" class="btn btn-primary" value="Save">
            <button v-on:click="cancelEdit(movie['.key'])">Cancel</button>
          </form>
        </div>

      </div>

    </div>
 
    <div class="panel panel-default">
      <div class="panel-heading">
        <h3>Movies List</h3>
      </div>
      <div class="panel-body">
        <table class="table table-stripped">
          <thead>
            <tr>
              <th>Title</th>
              <th>director</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="movie in movies">

              <td>
                <a v-bind:href="movie.url" v-bind:key="movie['.key']" target="_blank">{{movie.title}}</a>
              </td>
              <td>
                {{movie.director}}
              </td>
              <td>
                <button v-on:click="editMovie(movie)">Edit</button>
              </td>
              <td>
                <button v-on:click="removeMovie(movie)">Remove</button>
              </td>

            </tr>
          </tbody>
        </table>
      </div>
    </div>
  </div>
</template>

<script>

import { moviesRef } from './firebase'

export default {
  name: 'app',
  firebase: {
    movies: moviesRef
  },
  data () {
    return {
      isEditing: false, // maybe this helps?
      newMovie: {
        title: '',
        director: '',
        url: 'http://',
        edit: false // or maybe this??
      }
    }
  },
  methods: {
    addMovie: function() {
      moviesRef.push( this.newMovie )
      this.newMovie.title = '',
      this.newMovie.director = '',
      this.newMovie.url = 'http://'
      this.newMovie.edit = false
    },
    editMovie: function (movie){
      moviesRef.child(movie['.key']).update({ edit:true }); // can't access this one with v-if, not sure why
      //this.newMovie = movie;
    },
    removeMovie: function (movie) {
      moviesRef.child(movie['.key']).remove()
    },
    cancelEdit(key){
      moviesRef.child(key).update({ edit:false })
    },
    saveEdit(movie){
      const key = movie['key'];
      moviesRef.child(key).set({
        title    : movie.title,
        director : movie.director,
        url      : movie.url,
        edit     : movie.edit
      })
    }
  }
}

</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

您应该在单击 Edit 按钮时将 isEditing 更改为 true,并且您应该定义数据 movie.

editMovie: function (movie){
  ...
  this.movie = Vue.util.extend({}, movie); // deep clone to prevent modify the original object
  this.isEditing = true;
},

按照评论中的建议(Ben),我将电影声明添加到初始数据对象。所以现在看起来像这样:

data () {
    return {
      isEditing: false,
      newMovie: {
        title: '',
        director: '',
        url: 'http://',
        edit: false
      },
      movie: {
        edit: false
      }
    }
  },

现在 v-if 工作正常,像这样:

<div v-if="!movie.edit">

"is Editing" 不再需要,所以我删除了它。