如何查找需要更新的.vue文件中的HTML元素:

时间:2017-04-13 12:16:02

标签: vue.js vuejs2 vue-component

你可以认为我是 vuejs worlđ

的小孩

在我的应用程序中,我获取了firebase数据库中存在的一些帖子

每个帖子都有一个 upvote downvote 按钮,就像堆栈溢出一样,用户可以通过upvote或downvote(这完全取决于他们)

*如果选票更新到databae并且所有作品都很好**

问题出现了

Firebase提供了一个事件监听器,可以在每个孩子发生变化时进行监听,即发布(在我的情况下是upvotes。Downvotes)

我将此侦听器添加到created()生命周期钩子中,以便在其他用户对其进行更改时更新投票

以下是我的.vue文件的简化代码

<template>
    <div>
        <div v-for="post in posts" id="post.key" class="container">
            <p id="upvotes">{{ post.up}}</p>
            <p id="downvotes">{{ post.down }}</p>
          </div>
    </div>
</template>

<script>

    export default{
        created:{
            const ref = this.$firebase.database().ref(); 
                ref.child("posts").on('child_changed', function(post) {
                    var upvotes = post.val().up;
                    var downvotes = post.val().down;

                    //how to look up the element in the HTML above that needs to be updated:
                    //if it were plain javascript we would have done something like this

                    //var postElm = document.getElementById(post.key);
                    //postElm.getElementById("upvotes").innerHTML = upvotes;
                    //postElm.getElementById("downvotes").innerHTML = downvotes;
                });
        }
    }
</script>

我的问题:

  • 如何在需要更新的模板中查找上面HTML中的upvotes和downvotes元素:

  • 根据docs,我们可以向元素注册引用ref,但有一条说明:

因为refs本身是由渲染函数创建的,所以你无法在初始渲染时访问它们 - 它们还不存在! $refs也是非反应性的,因此您不应尝试在数据绑定模板中使用它。

所以如何引用元素来更新它们

1 个答案:

答案 0 :(得分:0)

更新:这是一个我嘲笑firebase行为的例子。 posts应该是data项,因为您可以控制其内容。 computed项是基于其他dataprops项的派生值。你不会根据Vue外部的值制作computed,因为这些值不是被动的。

&#13;
&#13;
const payloads = [{
    val() {
      return {
        key: 2,
        up: 10,
        down: 3
      };
    }
  },
  {
    val() {
      return {
        key: 1,
        up: 3,
        down: 10
      };
    }
  }
];


new Vue({
  el: '#app',
  components: {
    postVoter: {
      template: '#post-voter-template',
      data() {
        return {
          posts: [{
              key: 1,
              up: 0,
              down: 0
            },
            {
              key: 2,
              up: 1,
              down: 0
            },
            {
              key: 3,
              up: 0,
              down: 1
            }
          ]
        }
      },
      created() {
        const i = setInterval(() => {
          if (payloads.length) {
            console.log("Doing");
            const post = payloads.shift();
            const item = this.posts.find((p) => p.key === post.val().key);

            item.up = post.val().up;
            item.down = post.val().down;
          } else {
            console.log("Done");
            clearInterval(i);
          }
        }, 1000);
      }
    }
  }
});
&#13;
.container {
  display: flex;
  justify-content: space-between;
  width: 10rem;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.min.js"></script>
<template id="post-voter-template">
    <div>
        <div v-for="post in posts" class="container">
            <p id="upvotes">{{ post.up}}</p>
            <p id="downvotes">{{ post.down }}</p>
          </div>
    </div>
</template>

<post-voter id="app"></post-voter>
&#13;
&#13;
&#13;

您应该找到哪些数据项需要更新,而不是尝试在DOM中找到它。你不会说posts是如何创建或填充的,所以我不得不推测它的外观。代码应该是这样的:

<template>
    <div>
        <div v-for="post in posts" class="container">
            <p id="upvotes">{{ post.up}}</p>
            <p id="downvotes">{{ post.down }}</p>
          </div>
    </div>
</template>

<script>

    export default{

        created() {
            const ref = this.$firebase.database().ref(); 

            ref.child("posts").on('child_changed', (post) => {
                const item = this.posts.find((p) => p.key === post.key);

                item.up = post.val().up;
                item.down = post.val().down;
            });
        }
    }
</script>