访问已装入的数据变量返回未定义

时间:2019-10-04 13:13:42

标签: javascript vue.js

我正在尝试基于Vue.js和socket.io建立一个简单的聊天室。我有一个正常的get呼叫来获取所有明显的消息,此消息工作正常并且视图得到更新。

但是当我尝试从socket.io块中更新消息时,收到一条错误消息,提示this.messages is undefined。我看着vue调试器,不会推送新消息。

这是范围问题吗?

这是我的Chat.vue

<template>
    <div class="chat">
        <h1>Chat</h1>
        <ul id="messages" class="messages">
            <li v-for="message in messages" v-bind:key="message.timestamp">
                {{ message.timestamp }}: {{ message.text }}
            </li>
        </ul>
    </div>
</template>


<script>
    import axios from "axios";
    import io from 'socket.io-client';

    export default {
        data: function() {
            return {
                messages: [{
                    timestamp: null,
                    message: ""
                }]
            }
        },
        mounted: function() {
            this.fetch();
            let socket = io();
            socket.on('chat message', function (msg) {
                // This fails with the error message
                this.messages.push(JSON.parse(msg));
            });
        },
        methods: {
            fetch() {

                axios.get('http://localhost:8080/api/messages').then((response) => {
                    response = JSON.parse(response.data);
                    // This works without a problem
                    this.messages = response;
                });
            }
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
    .messages {
        list-style-type: none;
    }
</style>

1 个答案:

答案 0 :(得分:3)

在调用函数(非vue函数)时,其范围已更改。

socket.on('chat message', function (msg) {
   // This fails with the error message
   this.messages.push(JSON.parse(msg));
});

因此,在这种情况下,这不再与您的上下文相关联,并且this.messages将是未定义的。因此,您必须将此绑定到方法。

您可以使用旧的方式使用function() {}.bind(this),但是由于我们目前拥有ES6,因此不再使用它。我们使用箭头功能。有关箭头功能的完整详细信息:(https://www.w3schools.com/js/js_arrow_function.asp

socket.on('chat message', (msg) => {
   // This fails with the error message
   this.messages.push(JSON.parse(msg));
});