Nuxt/examples/with-sockets/pages/index.vue

158 lines
2.5 KiB
Vue

<template>
<div>
<ul class="pages">
<li class="chat page">
<div class="chatArea">
<ul ref="messages" class="messages">
<li v-for="(message, index) in messages" :key="index" class="message">
<i :title="message.date">
{{ message.date.split('T')[1].slice(0, -2) }}
</i>: {{ message.text }}
</li>
</ul>
</div>
<input v-model="message" class="inputMessage" type="text" placeholder="Type here..." @keyup.enter="sendMessage">
</li>
</ul>
</div>
</template>
<script>
import socket from '~/plugins/socket.io.js'
export default {
asyncData(context, callback) {
socket.emit('last-messages', function (messages) {
callback(null, {
messages,
message: ''
})
})
},
watch: {
'messages': 'scrollToBottom'
},
beforeMount() {
socket.on('new-message', (message) => {
this.messages.push(message)
})
},
mounted() {
this.scrollToBottom()
},
methods: {
sendMessage() {
if (!this.message.trim()) return
const message = {
date: new Date().toJSON(),
text: this.message.trim()
}
this.messages.push(message)
this.message = ''
socket.emit('send-message', message)
},
scrollToBottom() {
this.$nextTick(() => {
this.$refs.messages.scrollTop = this.$refs.messages.scrollHeight
})
}
},
head: {
title: 'Nuxt.js with Socket.io'
}
}
</script>
<style>
* {
box-sizing: border-box;
}
html {
font-weight: 300;
-webkit-font-smoothing: antialiased;
}
html, input {
font-family:
"HelveticaNeue-Light",
"Helvetica Neue Light",
"Helvetica Neue",
Helvetica,
Arial,
"Lucida Grande",
sans-serif;
}
html, body {
height: 100%;
margin: 0;
padding: 0;
}
ul {
list-style: none;
word-wrap: break-word;
}
/* Pages */
.pages {
height: 100%;
margin: 0;
padding: 0;
width: 100%;
}
.page {
height: 100%;
position: absolute;
width: 100%;
}
/* Font */
.messages {
font-size: 150%;
}
.inputMessage {
font-size: 100%;
}
.log {
color: gray;
font-size: 70%;
margin: 5px;
text-align: center;
}
/* Messages */
.chatArea {
height: 100%;
padding-bottom: 60px;
}
.messages {
height: 100%;
margin: 0;
overflow-y: scroll;
padding: 10px 20px 10px 20px;
}
/* Input */
.inputMessage {
border: 10px solid #3B8070;
bottom: 0;
height: 60px;
left: 0;
outline: none;
padding-left: 10px;
position: absolute;
right: 0;
width: 100%;
}
</style>