简体   繁体   中英

Vue.js not rendering elements in a list

so, for context, I have a client-side for an app where the server sends the client the client's friends over a socket connection. I can retrieve the friends, and even create clickable list elements so that the user can send a message to a friend, etc. However the one problem that I am having is that when using the mustache syntax to render information, nothing renders. I have the following code.

index.html (the following is inside the app div)

<div id="friends">
                <p>Friends</p>
                <ul id="friend-list">
                    <li 
                        v-for="friend in friends"
                        v-on:click="setFriend(friend.id)"
                        >Friend:{{friend.text}}
                    </li>
                </ul>
            </div>

index.js

var socket = io.connect('http://localhost:3000');
var app = new Vue({
    el: '#app',
    data: {
        messageContent: '',
        friends: [],
        messages: []
    }
})
socket.on('connect', function(){
  socket.emit('authentication', Cookies.get('user'));
  socket.on('authenticated', function() {
  socket.on('sendFriends',(data) => {
        data.forEach(element => {
            console.log(element.username)
            app.friends.push({
                text: element.username + '.'+element.id, 
                id: element.id
            })

        })
        toUser = app.friends[0].id
    })
})
})

Even if I were to fill the friends array without data from the socket connection, the text on each element would not render. By this I mean, there would be bullet points which have the on click function, however no text. However, when I create a codepen, the data is rendered correctly. Does this have to do with the socket connection and how Vue reacts to data change? https://codepen.io/dvub/pen/XWaebyb (codepen link)

Since API calls are asynchronous, Vue is already reading the values of friends before the call is processed and the data is received. So Vue is already started looping over the friends array before anything has come back from the API.

The individual friend is passed as a prop to a child component. The child component inturn is now looking for properties on that object (ie, friend.name ).

But the friends array is empty when the component is first mounted. Therefore adding a simple v-if to stop the rendering until you have received the information is needed.

<ul id="friend-list" v-if="friends.length">

You may also want to remove

toUser = app.friends[0].id

It does not look like valid JS syntax (where is toUser declared?).

You can't set properly friends values unless you're into the Vue's app context. So you should begin to put back all the stuff into your Vue app. It should looks more like something (I can't guarantee it works since I don't know how your socket lib works, but this is how it should be structured) :

<div id="friends">
    <p>Friends</p>
    <ul id="friend-list">
        <li v-for="friend in friends"
            v-on:click="setFriend(friend.id)">Friend:{{friend.text}}
        </li>
    </ul>
</div>
const app = new Vue({
    el: '#app',
    data: {
        socket: null,
        messageContent: '',
        friends: [],
        messages: []
    },
    mounted: {
        // Here it depends on how the library works. You may have to use async / await on connection init :
        this socket = io.connect('http://localhost:3000');
        this.socket.on('connect', function(){
            this.socket.emit('authentication', Cookies.get('user'));
            this.socket.on('authenticated', function() {
            this.socket.on('sendFriends',(data) => {
                data.forEach(element => {
                    console.log(element.username)
                    this.friends.push({
                        text: element.username + '.'+element.id, 
                        id: element.id
                    });
                });
            });
            // I don't know what you're trying to do here so I commented this one :
            // toUser = app.friends[0].id
        });
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM