Vue. js + socket.io как обновить реквизиты - PullRequest
2 голосов
/ 20 июня 2020

Итак, это мой компонент списка пользователей для Vue. Socket.io возвращает список активных пользователей, например [{name: Fluxed, rank: Admin}], и я хочу, чтобы он автоматически обновлял элемент. Как я могу обновить элемент prop, а затем показать изменения?

Вот мой код

<template>
  <div id="app">
    <div>
    <div style="float:right;width:30%;border-left:1px solid black;padding:1%;">
      <b>Users</b>
      <b-list-group style="max-width: 300px;" >
        <b-list-group-item class="align-items-center" v-for="value in userList2" v-bind:key="value.name" >
          <b-avatar class="mr-3"></b-avatar>
          <span class="mr-auto">{{ value.name }}</span>
          <b-badge>{{ value.rank }}</b-badge>
        </b-list-group-item>
      </b-list-group>
      <ul class="list-group">
      </ul>
    </div>
  </div>
  </div>
</template>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>

<script>
import io from 'socket.io-client';
import $ from 'jquery'
var socket = io('http://localhost:4000');
socket.on('update', function (users){
      this.userList = users;
      console.log(this.userList)
}) 
import VueJwtDecode from "vue-jwt-decode";
export default {
  
  name: 'app',
  props: {
    userList2: {
      type: Array,
      default: () => []
    }
  },
  data() {
    
    return {
      user: {},
      componentKey: 0,
      userList: this.userList2,
      
    };
  },
  
  created () {
    // get socket somehow
    socket.on('update', function (users){
      console.log(this.userList)
      this.userList = users;
      console.log(this.userList)
    }) 
  },
  methods: {
    async getUserDetails() {
      let token = localStorage.getItem("jwt");
      let decoded = VueJwtDecode.decode(token);
      let response = await this.$http.post("/update", decoded);
      let urank = response.data.rank;
      this.user = decoded;
      this.user.rank = urank;
    },
    logUserOut() {
      localStorage.removeItem("jwt");
      this.$router.push("/");
    },
    
  },
}
</script>

Как мне сделать автообновление группового элемента Vue bootstrap один раз изменение происходит с socket.io?

Ответы [ 3 ]

1 голос
/ 20 июня 2020

Обзор:

Вы можете $emit event с обновленным списком вернуться к родительскому элементу, а затем обновить свойство data в родительском компоненте. Это потому, что вы не должны напрямую изменять props.

Пример:

В дочернем компоненте:

import io from 'socket.io-client';

data() {
 return {
  socket: io()
 }
},
props: {
 userList2: {
  type: Array,
  default: () => []
 }
},
created() {
  this.socket.on('update', (users) => {
   this.$emit('updateListEv', users);
  })
}

, затем в родительском компоненте:

<childNameComponent @updateListEv="updateList"></childNameComponent>

, тогда вам понадобится в родительском компоненте, чтобы фактически обновить свойство data данными, переданными обратно из дочернего компонента.

methods: {
  updateList(updatedList) {
   this.userList2 = updatedList
  }
}

Примечание:

Вы должны иметь возможность использовать свой prop напрямую, если вы делаете это таким образом, поэтому нет необходимости устанавливать дополнительное свойство data в дочернем компоненте - userList: this.userList2.

В этом случае вы будете перебирать userList2 точно так же, как и сейчас - v-for="value in userList2"

Вы также можете видеть, что в этом случае , мы инициализируем сокет как свойство data, чтобы мы могли использовать его в нашем экземпляре Vue.

Изменить:

import io from 'socket.io-client';
data() {
  return {
    socket: io(),
    usersList: this.userList2
  }
},
props: {
 userList2: {
  type: Array,
  default: () => []
 }
},
created() {
  this.socket.on('update', (users) => {
   this.userList = users
  })
}

в вашем HTML шаблоне l oop через список пользователей:

v-for="value in usersList"

Использование socket.io с Vue. js и Node.js полный пример:

В вашем бэкэнде (Node.js):

//setting up sockets
const app = express()
const server = http.createServer(app)
const io = require('socket.io')(server)
io.on('connection', (socket) => {
  socket.on('sendUpdateList', function(data) {
    io.emit('listUpdate', data)
  });
})

Отправка обновления из компонента:

import io from 'socket.io-client';

data() {
 return {
  socket: io(),
  usersList: []
 }
},
methods: {
 this.socket.emit('sendUpdateList', {usersList: this.usersList})
}

Прослушивание сокета в компоненте:

import io from 'socket.io-client';

data() {
 return {
  socket: io(),
  usersList: []
 }
},
created() {
  this.socket.on('listUpdate', (data) => {
   this.usersList = data.usersList
  })
}
1 голос
/ 20 июня 2020

Сложно сказать, поскольку мы не можем запустить ваш код, но, бегло взглянув на него, я думаю, что это так просто:

Замените userList2 в v-for="value in userList2" на userList.

Если вы собираетесь больше работать с сокетами и Vue, я думаю, что vue -socket.io - весьма полезная библиотека: https://www.npmjs.com/package/vue-socket.io

0 голосов
/ 20 июня 2020

this внутри обратного вызова socket.on('update' не то, что вы думаете (это не компонент vue), поэтому присвоение this.userList не вызовет никаких изменений в компоненте vue ).

Используйте функцию и стрелку в качестве обратного вызова, чтобы он использовал окружающий this (который является вашим компонентом) следующим образом:

import io from 'socket.io-client';
import $ from 'jquery'
import VueJwtDecode from "vue-jwt-decode";

var socket = io('http://localhost:4000');

export default {
  name: 'app',
  props: {
    userList2: {
      type: Array,
      default: () => []
    }
  },
  data() {
    
    return {
      user: {},
      componentKey: 0,
      userList: this.userList2,
      
    };
  },
  
  created () {
    socket.on('update', users => {      // arrow function here so 'this' keyword inside will refer to your vue component
      this.userList = users;            // either this one
      this.userList2 = users;           // or this one (I don't know why you are using two props for this btw)
    }) 
  },
  // ...
}

Подробнее о this и почему стрелочные функции не имеют их в этом другом вопросе SO: Как работает ключевое слово «this»?

...