使用 VueFire 编辑 Firebase 数据

Posted

技术标签:

【中文标题】使用 VueFire 编辑 Firebase 数据【英文标题】:Edit Firebase data using VueFire 【发布时间】:2017-07-31 04:03:30 【问题描述】:

我有一个简单的 admin 应用程序,它通过表单创建新的 businesses 并将它们添加到表中。我已经创建了添加和删除条目的方法,但不确定如何继续创建更新方法。内容是 contenteditable,我想在单击保存按钮时保存它。请查看我的 CodePen:http://codepen.io/Auzy/pen/177244afc7cb487905b927dd3a32ae61 为此,我以以下方式使用 VueJS 和 Vuefire(请原谅 Bootstrap):

  <!-- Table -->
  <table class="table table-striped">
  <tr>
    <th>Business Name</th>
    <th>Vanity URL</th>
        <th>Story</th>
    <th>Actions</th>
  </tr>
  <tr v-for="post in posts" :key="post['.key']">
    <td contenteditable v-model="newPost.title">post.title</td>
    <td>post.content</td>
        <td>post.story</td>
    <td>
              <button v-on:click="removePost(post)" type="button" class="btn btn-default btn-sm"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit</button>
  <button v-on:click="removePost(post)" type="button" class="btn btn-danger btn-sm"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span> Delete</button>
        </td>
  </tr>
  </table>
</div>
</div>

还有 JS:

// Setup Firebase
let config = 
  ...firebase stuff...


let firebaseapp = firebase.initializeApp(config);
let db = firebaseapp.database();
let postsRef = db.ref('blog/posts')

// create Vue app
var app = new Vue(
  // element to mount to
  el: '#app',
  // initial data

  data: 
    newPost: 
      title: '',
      content: '',
            story: ''
    
  ,
  // firebase binding
  // https://github.com/vuejs/vuefire
  firebase: 
    posts: postsRef
  ,
  // methods
  methods: 
      addPost: function () 
        postsRef.push(this.newPost);
        this.newPost.title = '';
        this.newPost.content = '';
        this.newPost.story = '';
      ,
    removePost: function (post) 
      postsRef.child(post['.key']).remove()
            toastr.success('Business removed successfully')
    
  
)

【问题讨论】:

【参考方案1】:

您必须将 $bindAsArray 用于数组,将 $bindAsObject 用于对象,以将 Firebase 数据绑定到组件数据。

您可以使用vuefire 提供的$firebaseRefs 来更新或修改端点。

这是更新后的codepen。

我对您的代码进行了以下更改。

// create Vue app
var app = new Vue(
  // element to mount to
  el: '#app',
  // initial data

  data: 
    posts: [], // All the business post to display
    newPost: 
      title: '',
      content: '',
      story: ''
    
  ,
  // methods
  methods: 
        addPost: function () 
            postsRef.push(this.newPost);
            this.newPost.title = '';
            this.newPost.content = '';
            this.newPost.story = '';
        ,
        editPost: function(post) 
            // Set post values to form
            this.newPost = post
        ,
        updatePost: function(post) 
            const childKey = post['.key'];
            /*
             * Firebase doesn't accept speacial chars as value
             * so delete `.key` property from the post
             */
            delete post['.key'];
            /*
             * Set the updated post value
             */
            this.$firebaseRefs.posts.child(childKey).set(post)
        , 
        removePost: function (post) 
         postsRef.child(post['.key']).remove()
         toastr.success('Business removed successfully')
        , 

  ,
    // Explicitly set binding data to firebase as an array.
    created() 
        this.$bindAsArray('posts', postsRef);
    
)

在模板中:

<div id="app">
 <ul class="nav nav-pills nav-justify">
        <li role="presentation" class="active"><a href="#">Businesses</a></li>
        <li role="presentation"><a href="#">Events</a></li>
        <li role="presentation"><a href="#">Locations</a></li>
 </ul>
 <br />
  <div class="panel panel-default">
    <div class="panel-heading">
     <h3 class="panel-title">Add a Business</h3>
    </div>
    <div class="panel-body">
     <form id="form">
      <div class="form-group">
        <label for="exampleInputPassword1">Business Name</label>
        <input v-model="newPost.title" type="text" class="form-control" id="exampleInputPassword1" placeholder="Business Name">
      </div>

      <div class="form-group">
        <label for="basic-url">Vanity URL</label>
        <div class="input-group">
        <span class="input-group-addon" id="basic-addon3">/businesses/</span>
        <input v-model="newPost.content" type="text" class="form-control" id="basic-url" aria-describedby="basic-addon3">
      </div>
    </div>
    <div class="form-group">
     <label for="basic-url">Description</label>
     <textarea v-model="newPost.story" name="" id="" cols="30" rows="10"></textarea>
     </div>
     <button type="button" class="btn btn-default" v-if="newPost['.key']" v-on:click="updatePost(newPost)">Update</button>
     <button type="submit" class="btn btn-default" v-if="!newPost['.key']" v-on:click="addPost">Add Business</button>
</form>
</div>
    </div>

    <div class="panel panel-default">
        <!-- Default panel contents -->
        <div class="panel-heading">Businesses</div>

        <!-- Table -->
        <table class="table table-striped">
            <tr>
                <th>Business Name</th>
                <th>Vanity URL</th>
                <th>Story</th>
                <th>Actions</th>
            </tr>
            <tr v-for="post in posts" :key="post['.key']">
                <td contenteditable v-model="newPost.title">post.title</td>
                <td>post.content</td>
                <td>post.story</td>
                <td>
                    <button v-on:click="editPost(post)" type="button" class="btn btn-default btn-sm"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit</button>
                    <button v-on:click="removePost(post)" type="button" class="btn btn-danger btn-sm"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span> Delete</button>
                </td>
            </tr>
        </table>
    </div>

    <ul class="errors">
    </ul>
</div>

【讨论】:

Srinivas Damam,我在 codepen 中查看了您的示例,我意识到它与我正在寻找解决的问题相同。当您单击编辑按钮时,您只需调用 'editPost' 方法,但如果您调用 'updatePost' 并对帖子进行真正的更改,例如:post.title = "foo,您会注意到它不仅更改了您点击的帖子还有另一个帖子。您知道为什么吗?

以上是关于使用 VueFire 编辑 Firebase 数据的主要内容,如果未能解决你的问题,请参考以下文章

在 Vuejs 中渲染 DOM 之前,使用路由器中的参数获取 firebase 数据(使用或不使用 vuefire)?

Vue.js 上带有图表的 Vuefire

Firebase 和 Vue:如何正确初始化 firebase 和 vuefire?

在 vuefire 的 firestore 内的“this”中获取“undefined”

如何让 vuefire 显示加载屏幕?

firebase(firestore)和vuejs + vuefire的非常奇怪的反应性问题