vuejs对异步更新的组件数据有何反应

时间:2019-02-12 12:45:31

标签: vuejs2

我对vuejs非常陌生,最近开始尝试替换一些旧的jquery代码,并使之与vuejs反应。关键是我有一个组件,可通过socket.io异步地从nodejs服务器获取信息。

当我获取数据并更新组件的数据时,我在控制台记录日志时看到了更改,但是它并没有以我想要的方式更改DOM。

异步获取数据并在组件内部使用它的正确方法是什么?我发布了代码的某些部分,以便您可以看到。我会很感激您能给我的任何建议。预先感谢!

Vue.component('chat', {
      data() {
        return {
          chat: null,
          commands: [],
          chatOpened: false,
        }
      },

      props: [
        'io',
        'messages',
        'channels',
        'connectChat',
        'roomChat',
        'user',
        'userId',
        'soundRoute',
      ],

      methods: {
        openChat() {
          this.chatOpened = true;
        },

        closeChat() {
          this.chatOpened = false;
        },
      },

      created() {
        this.chat = this.$io.connect(this.connectChat);
        this.commands.push('clear');

        let self = this;

        $.each(this.channels, function(index, value) {
          self.chat.emit('join', {room: index, user: self.user, userId: self.userId}, function(err, cb) {
            if (!err) {
              users = cb.users;
              messages = cb.messages;

              if (messages.length > 0) {
                self.channels[index].loaded = true;
              }

              //some more code
            }
          });
        });

        console.log(this.channels);
      },

      template: `
          <div>
            <div id="container-chat-open-button" @click="openChat" :class="{hide : chatOpened}">
              <div>+90</div>
              <i class="fas fa-comment-alt"></i>
            </div>
            <div id="container-chat" class="chat__container" :class="{open : chatOpened}">
              <div id="container-chat-close-button" @click="closeChat">
                <span>
                  <div>
                    <i class="fas fa-comment-alt"></i>
                    @{{ messages.chat_lobby_icon_title }}
                  </div>
                  <i class="icon-arrowdown"></i>
                </span>
              </div>
              <div id="alert-chat" class="chat__container-notifications animated flash"></div>
              <div class="row">
                <ul>
                  <li v-for="channel in channels" v-show="channel.loaded === true">Channel loaded</li>
                </ul>
              </div>
            </div>
          </div>
        `
      });

我希望看到带有消息的频道列表,但我什至以为我看不到自己的频道,其已加载属性设置为true(默认情况下,所有这些属性都设置为false)。 / p>

1 个答案:

答案 0 :(得分:0)

我的猜测是,这部分无法正常工作。

if (messages.length > 0) {
   self.channels[index].loaded = true;
}

反应的方法是再次设置完整对象。

Vue.set(self.channels, index, {
   ...self.channels[index],
   loaded: true
}

编辑1:

this.channels.forEach((channel) => {
    this.chat.emit('join', {room: index, user: self.user, userId: self.userId}, (err, cb) => {
        if (!err) {
            users = cb.users;
            messages = cb.messages;

            if (messages.length > 0) {
                Vue.set(self.channels, index, {
                    ...self.channels[index],
                    loaded: true
                }
            }

            //some more code
        }
    });
})

您需要使用babel添加对rest-spread-operator的支持。