Nuxt.js mini聊天室代码

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Co_zy/article/details/81034243

写代码时关闭了ESlinting,导致有些地方不是特别规范

改进

  • 发送表情符号
  • 发送语音

login界面

<template>
  <div class="login-panel">
    <div class="login">
      <h1 class="title">迷你聊天室</h1>
      <label for="">输入名字开始聊天</label>
      <!-- <input type="text" name="" class="input is-primary"> -->
      <div class="control">
        <input class="input" type="text" placeholder="" v-model="username">
      </div>
      <button type="button" class="button is-primary" @click="enter">进入聊天</button>
    </div>
  </div>
</template>
<style scoped>
.title{
    margin:40px;
    padding-left: 40px;
    padding-bottom: 80px;
}
.login-panel {
  /*height: 400px;
  width: 400px;
  margin: 0px auto;
  margin-top: 120px;*/
  height: 416px;
  /*position: relative;*/
  border: 1px solid #d7d7d7;
  box-shadow: 0 0 10px #d7d7d7;
  background-color: #fff;
  position: absolute;
  width: 382px;
  color: #818181;
  margin: 80px auto;
  position: absolute;
  left: 0;
  right: 0;
}
.button.is-primary {
  margin-top: 20px;
  line-height: 0px;
  margin-left: 102px;
}

.control {
  margin-top: 20px;
}
label{
    margin-left: 113px;
}
.input{
    width: 80%;
    margin-left: 36px;
}
</style>
<script>
export default {
  data() {
    return {
      username: ''
    }
  },
  methods: {
    enter() {
      //console.log('username', this.username)
      this.$router.push("/chat?username=" + this.username)
    }
  }
}

</script>

chat界面

<template>
  <div class="chat">
    <div class="messages-list">
      <div class="content" v-for="(m, i) in messages" :key="i">
        <div class="who"><img src="../assets/img/6.png" alt=""> {{m.who}}:</div>
        <div class="message-content"><span>{{m.message}}</span></div>
        <br>
      </div>
    </div>
    <div class="controls">
      <div class="field has-addons">
        <p class="control is-expanded">
          <input class="input" type="text" @keypress.enter="send" v-model="inputMessage" />
        </p>
        <p class="control">
          <button class="button is-primary" type="button" @click="send">发送</button>
        </p>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      'messages': [],
      'inputMessage': ''
    }
  },

  async asyncData({ app, query }) {
    let messages = await app.$axios.$get('/api/messages')
    let username = query.username || '未知用户'
    // console.log(messages)
    return { 'messages': messages, username }
  },

  async mounted() {
    //无参箭头函数() => {}
    this.$timer = setInterval(() => {
      let lastId = 0
      if (this.messages.length > 0) {
        lastId = this.messages[this.messages.length - 1].id
      }
      this.$axios.$get('/api/messages?lastId=' + lastId)
        .then(messages => {
          this.messages.push(...messages)
        })
    }, 3000)
  },

  destroyed() {
    if (this.$timer) {
      clearInterval(this.$timer)
    }
  },

  methods: {
    async send() {
      let message = this.inputMessage
      // console.log('message in send:', message)
      await this.$axios.$post('/api/messages', { who: this.username, 'message': message })
      this.inputMessage = ''
    }
    // sendOld() {
    //   this.messages.push({
    //     who: 'wu',
    //     message: this.inputMessage
    //   })
    //   this.inputMessage = ''
    // },
  }
}

</script>

<style scoped>
.who {
  /*margin-bottom: 10px;*/
  /*float: left;*/
  display: inline-block;
}

.chat {
  /*height: 300px;*/
  /*padding-bottom: 64px;*/
  /*height: 500px;*/
  /*position: relative;*/
  /*height: 100%;*/
  border: 1px solid #d7d7d7;
  box-shadow: 0 0 20px #d7d7d7;
  background-color: #fff;
  position: absolute;
  width: 382px;
  color: #818181;
  margin: 80px auto;
  position: absolute;
  left: 0;
  right: 0;
}

.controls {
  position: fixed;
  bottom: 0;
  height: 64px;
  width: 382px;
  /*border-top: 1px solid black;*/
  background-color: white;
}

.messages-list {
  padding: 10px;
  /*overflow-y: scroll;*/
  margin-bottom: 64px;
}

.message-content {
  padding-left: 1em;
  /*float: left;*/
  display: inline-block;
}

.message-content span {
  background-color: #e0e0e0;
  padding: 5px;
  border-radius: 5px;
}

.button.is-primary {
  line-height: 0px;
}

img {
  height: 30px;
  width: 30px;
}

</style>

服务端index.js代码

import Koa from 'koa'
import koaBody from 'koa-body'

import { Nuxt, Builder } from 'nuxt'

async function start () {
  const app = new Koa()
  const host = process.env.HOST || '127.0.0.1'
  const port = process.env.PORT || 3000

  // Import and Set Nuxt.js options
  let config = require('../nuxt.config.js')
  config.dev = !(app.env === 'production')

  // Instantiate nuxt.js
  const nuxt = new Nuxt(config)

  // Build in development
  if (config.dev) {
    const builder = new Builder(nuxt)
    await builder.build()
  }

  let messages = []
  let globalMessageId = 1

  // 解析客户端请求,并将得到的数据放在 ctx.request.body
  app.use(koaBody())

  // 服务端接口实现:
  app.use(async (ctx, next) => {
    // 提供一个服务器接口,实现获取 服务器的消息列表 messages
    // GET /api/messages
    if ('GET'.toUpperCase() === ctx.request.method &&
      ctx.request.path === '/api/messages') {
      //标志旧消息
      let lastId = 0
      if (ctx.request.query.lastId) {
        lastId = parseInt(ctx.request.query.lastId)
      }
      for (let i = messages.length - 1; i >= 0; i--) {
        if (messages[i].id === lastId) {
          //取出消息数组中最新的消息
          ctx.response.body = messages.slice(i + 1)
          return
        }
      }
      ctx.response.body = messages
    } else if ('POST'.toUpperCase() === ctx.request.method &&
      ctx.request.path === '/api/messages') {
      // 客户端发送消息的接口,服务器接受到消息后,放入消息大列表中

      let message = ctx.request.body
      message.id = globalMessageId
      globalMessageId++
      // console.log('received message:', message)
      messages.push(message)
      ctx.response.body = { status: 0 }
    } else {
      await next()
    }
  })

  app.use(async (ctx, next) => {
    await next()
    ctx.status = 200 // koa defaults to 404 when it sees that status is unset
    return new Promise((resolve, reject) => {
      ctx.res.on('close', resolve)
      ctx.res.on('finish', resolve)
      nuxt.render(ctx.req, ctx.res, promise => {
        // nuxt.render passes a rejected promise into callback on error.
        promise.then(resolve).catch(reject)
      })
    })
  })

  app.listen(port, host)
  console.log('Server listening on ' + host + ':' + port) // eslint-disable-line no-console
}

start()

效果图

这里写图片描述

这里写图片描述

猜你喜欢

转载自blog.csdn.net/Co_zy/article/details/81034243