访问 mounted returns 未定义的数据变量

Access to data variable in mounted returns undefined

我正在尝试基于 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>

当调用函数(非 vue 函数)时,this 的作用域发生了变化。

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

所以在这种情况下 this 不再绑定到你的 vue 上下文,this.messages 将是 undefined。所以你必须绑定 this 到方法。

以旧方式,您可以使用 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));
});