I'm new to Vue.js, so wonder how this can be done in Vue instead jQuery?
The socket.io and jQuery will append
a <li>
each time when someone has typed something on the browser.
<!doctype html>
<html>
<head>
<title>Socket.IO chat</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font: 13px Helvetica, Arial; }
form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
#messages { list-style-type: none; margin: 0; padding: 0; }
#messages li { padding: 5px 10px; }
#messages li:nth-child(odd) { background: #eee; }
</style>
</head>
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script>
$(function () {
var socket = io();
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
socket.on('chat message', function(msg){
$('#messages').append($('<li>').text(msg));
});
});
</script>
<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
</body>
</html>
How is this done in Vue?
I tried:
$(function () {
var socket = io();
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
var app = new Vue({
el: '#app',
data: {
message: "Hello World"
},
created: function() {
socket.on('chat message', function(data) {
this.message = data.message;
}.bind(this));
}
});
});
in my new HTML:
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
<span id="app">{{ message }}</span>
</form>
It does not work obviously.
Any ideas?
You can do it the complete vuejs way even without using jquery like this:
html
<div id="app">
<form @submit.prevent="submitMsg">
<input id="m" autocomplete="off" v-model="inputMsg"/>
<button type="submit">Send</button>
<span>
<ul>
<li v-for="message in messages">{{message}}</li>
</ul>
</span>
</form>
</div>
script
var app = new Vue({
el: '#app',
data: {
socket: null,
inputMsg: '',
messages: []
},
created: function() {
this.socket = io();
this.socket.on('chat message', function(msg) {
this.messages.push(msg);
}.bind(this));
},
methods:{
submitMsg(){
this.socket.emit('chat message', this.inputMsg);
this.inputMsg = '';
}
}
});
So what''s happening:
Wrapped the whole html with a div of id='app'
so that it is controlled by vue
added a submit event on the form using @submit.prevent
which calls the method submitMsg
. The prevent
modifier prevents form from being actually submitting
setup a v-model
on the input which is two way data boun
now you can use the v-model
which is inputMsg
to get the value of the input and use it in the form submission method
after emitting the socket event setting the input value empty using this.inputMsg = '';
in crated lifecycle hook setup a socket event listener and push message to the data property messages:[]
which is initialized as an empty array
loop trough the messages[]
in your template using v-for='message in messages'
which renders a <li>
element for every item in messages[]