render function or template not defined in component: anonymous

*爱你&永不变心* 提交于 2019-12-11 07:21:35

问题


I have such a problem, after reloading the page an error occurs."render function or template not defined in component: anonymous". I think the error is due to socket.io. What does this error do not occur on the local machine, but on the production. dev версия error

server.js

const APP_ENV = require('./.env.js')
const { Nuxt, Builder } = require('nuxt')
const app = require('express')()
let server = require('http').Server(app)

if(APP_ENV.ssl) {
  const fs = require('fs')
  const options = {
    key: fs.readFileSync(APP_ENV.ssl_key),
    cert: fs.readFileSync(APP_ENV.ssl_cert)
  }
  server = require('https').Server(options, app)
}

const port = process.env.PORT || APP_ENV.ws_port
const isProd = process.env.NODE_ENV === 'production'

// We instantiate Nuxt.js with the options
let config = require('./nuxt.config.js')
config.dev = !isProd

const nuxt = new Nuxt(config)
// Start build process in dev mode
if (config.dev) {
  const builder = new Builder(nuxt)
  builder.build()
}
app.use(nuxt.render)
if (APP_ENV.socket) {
  const io = require('socket.io')(server)
  const Redis = require('ioredis')
  const redis = new Redis(APP_ENV.redis.port, APP_ENV.redis.host)
  redis.psubscribe(['*'])
  redis.on('pmessage', function (subscribe, channel, message) {
    message = JSON.parse(message)
    console.log('Server: ', subscribe, channel, message.data.message)
    io.emit(channel + ':' + message.event, message.data)
  })

  // io.on('connection', function (socket) {
  // })
}

server.listen(port, function () {
  console.log('Listening on Port ' + port)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

plugins/socket.io.js

``

import io from 'socket.io-client'

const socket = io(process.env.WS_URL)

export default socket
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

io/index.js

module.exports = function () {
  const APP_ENV = require('../.env.js')
  const server = require('http').createServer(this.nuxt.renderer.app)

  // overwrite nuxt.listen()
  this.nuxt.listen = (port, host) => new Promise((resolve) => server.listen(port || 3000, host || 'localhost', resolve))
  // close this server on 'close' event
  this.nuxt.hook('close', () => new Promise((resolve) => server.close(resolve)))

  // Add `socket.io-client` in vendor
  this.addVendor('socket.io-client')

  if (APP_ENV.socket) {
    const io = require('socket.io')(server)
    const Redis = require('ioredis')
    const redis = new Redis(APP_ENV.redis.port, APP_ENV.redis.host)
    redis.psubscribe(['*'])
    redis.on('pmessage', function (subscribe, channel, message) {
      message = JSON.parse(message)
      console.log('Server: ', subscribe, channel, message.data.message)
      io.emit(channel + ':' + message.event, message.data)
    })

    // io.on('connection', function (socket) {
    // })
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

message/index.vue

<template>
  <div class="my-messages">
    <div class="container">
      <div class="row">
        <div class="col">
          <h3>Мои сообщения</h3>
        </div>
      </div>
      <div class="row">
        <div class="col">
          <div class="chat-wrap">
            <div class="chat-tabs__content active">
              <div class="chat-tabs">
                <!--<div class="chat-tabs__item active">Входящие <span v-if="userMessage.count > 0">{{ userMessage.count }}</span></div>-->
                <!--<div class="chat-tabs__item">Системные-->
                  <div v-for="(tab,index) in tabs" :key="index">
                    <div class="chat-tabs__item" @click="changeTab(index)" :class="{'chat-tabs__item active': tab.active}">{{tab.title}}
                  </div>
                  <!-- <span>1</span> -->
                </div>
              </div>
              <div class="chats-list">
                <div class="chats-list__body" data-simplebar >
                  <div class="">

                    <div class="chat-item" v-if="user.name != 'Системные' && tabs.incoming.active" @click.stop="chengeTab(index, user.id)" :class="{ active: tabUsers[index] }" v-for="(user, index) in userMessage.users" :key="index">
                      <div class="chat-item__ava">
                        <img v-if="user.user_avatar_path" :src="baseUrl + 'items-original/' + user.user_avatar_path" :alt="user.name">
                        <span v-else>{{ user.name[0] | uppercase }}{{ user.name[1] | uppercase }}</span>
                        <div v-if="user.unread > 0" class="chat-item__new-messages">{{ user.unread }}</div>
                      </div>
                      <div class="chat-item__interlocutor">
                        {{ user.name }}
                      </div>
                      <!--<div class="chat-item__last-messages" v-html="user.message">-->
                      <!--</div>-->
                      <div class="chat-item__data">
                        <!-- 13:25 -->
                      </div>
                    </div>
                  </div>
                </div>
              </div>
              <div v-if="!chat_mob" class="chats">
                <div class="chat-body active">
                  <div class="chat">
                    <div class="chat__header">
                      <div class="chat__interlocutor">
                        <div  class="chat-back" @click="chatBack">
                          <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
                               width="14.617px" height="8px" viewBox="0 0 14.617 8" style="enable-background:new 0 0 14.617 8;" xml:space="preserve">
                              <path style="fill:#DDE1E6;" d="M10.585,5.447c-0.85,0-1.7,0.013-2.549-0.003C6.603,5.418,6.419,5.531,6.489,6.973
                            c0.008,0.158-0.011,0.312-0.052,0.468C6.303,7.95,5.766,8.159,5.32,7.867C4.009,7.009,2.699,6.15,1.388,5.291
                            c-0.321-0.21-0.65-0.41-0.966-0.628C-0.131,4.282-0.146,3.7,0.41,3.332C2.011,2.271,3.626,1.23,5.23,0.171
                            C5.909-0.278,6.516,0.224,6.49,0.896C6.48,1.153,6.489,1.41,6.489,1.667c0,0.58,0.288,0.871,0.864,0.871c2.135,0,4.269,0,6.404,0
                            c0.573,0,0.859,0.291,0.86,0.876c0,0.415,0.003,0.83-0.001,1.245c-0.004,0.475-0.322,0.787-0.798,0.788
                            C12.74,5.447,11.663,5.447,10.585,5.447z"/>
                          </svg>
                        </div>
                        <div v-if="chatUser && (chatUser.name != 'Системные' && tabs.incoming.active )">{{ chatUser.name }}</div>
                      </div>
                      <!-- <div class="chat__actions">
                        <div class="chat-menu">
                          <div class="chat-menu__icon" @click.prevent="show = !show">
                            <svg class="icon-svg icon-svg-header-chat-menu"><use xlink:href="/img/sprite.svg#header-chat-menu"></use></svg>
                          </div>
                          <ul class="chat-menu__dropdown" :class="{ show: show }">
                            <li>
                              Отключить уведомения
                            </li>
                            <li>
                              Очистить историю
                            </li>
                            <li>
                              Заблокировать контакт
                            </li>
                          </ul>
                        </div>
                      </div> -->
                    </div>
                    <div class="chat__body" data-simplebar ref="chatBody">
                      <!-- <pre>
                        {{
                          chatMessage
                        }}
                      </pre> -->
                      <div id="message-container" v-if="chatMessage !== []">
                        <div class="message_wrapper" v-if="checkMessage(message.sender_id) && (message.sender_id != null && tabs.incoming.active)" v-for="(message, index) in chatMessage" :key="index">
                          <div class="message"  :class="{ 'message--to': userCurrent.id === message.sender_id, 'message--from': userCurrent.id !== message.sender_id }">
                            <div class="message__post-data"></div>

                            <div class="chat-item__ava message__ava" v-if="userByIdMessage(message.sender_id)" >
                              <img v-if="userByIdMessage(message.sender_id).user_avatar_path !== null" :src="baseUrl + 'items-original/' + userByIdMessage(message.sender_id).user_avatar_path" alt="" class="">
                              <div v-else >
                                <span>{{ userByIdMessage(message.sender_id).name[0] | uppercase }}{{ userByIdMessage(message.sender_id).name[1] | uppercase }}</span>
                              </div>
                            </div>
                            <div class="chat-item__ava message__ava" v-else>
                              <img v-if="userCurrent.user_avatar_path !== null" :src="baseUrl + 'items-original/' + userCurrent.user_avatar_path" alt="" class="">
                              <div v-else>
                                <span>{{ userCurrent.user_name[0] | uppercase }}{{ userCurrent.user_name[1] | uppercase }}</span>
                              </div>
                            </div>
                            <div class="message__text" v-html="message.message" >
                            </div>
                          </div>
                          <div class="chat-item__last-messages" :class="{ 'created_time_to': userCurrent.id === message.sender_id, 'created_time_from': userCurrent.id !== message.sender_id }">{{message.created_at}}</div>
                        </div>
                      </div>
                    </div>
                    <form class="chat__form">
                      <textarea placeholder="Введите сообщение..." @keyup.ctrl.enter="onSendMessage" v-model="message"></textarea>
                      <div v-html="img"></div>
                      <div class="chat__form-controls">
                        <div class="add-additions">
                          <label class="message_img" for="image"><img src="/img/affix.svg" alt=""></label>
                          <input class="img_input" id="image" type="file" accept="image/png, image/jpeg, image/gif, image/jpg" @change="uploadImg($event)">
                        </div>
                        <button @click.prevent="onSendMessage" >
                          <img src="/img/telega.svg" alt="">
                        </button>
                      </div>
                    </form>
                  </div>
                  <div class="interlocutor" v-if="chatUser">
                    <img
                      v-if="chatUser.user_avatar_path"
                      :src="baseUrl + 'items-original/' + chatUser.user_avatar_path"
                      :alt="chatUser.name"
                      class="interlocutor__img">
                    <img v-else
                         src="/img/avatar.svg"
                         :alt="chatUser.name"
                         class="interlocutor__img default_ava">

                    <div class="interlocutor__title">
                      {{ chatUser.name }}
                    </div>
                    <!--<ul class="interlocutor__info">-->
                      <!--<li>-->
                        <!--<span>-->
                          <!--<img src="/img/marker-icon.svg" alt="">-->
                        <!--</span>-->
                        <!--115280, Москва,-->
                        <!--ул. Ленинская слобода, д. 19-->
                      <!--</li>-->
                    <!--</ul>-->
                    <!--<p class="interlocutor__text">-->
                      <!--На сайте 5 мин., выставленно-->
                      <!--10 товаров. Время с момента регистрации 3 месяца.-->
                    <!--</p>-->
                    <!--<a href="#" class="btn btn&#45;&#45;xl btn&#45;&#45;border">-->
                      <!--Перейти к заказу-->
                    <!--</a>-->
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <!--<div class="container" v-else>-->
      <!--<div class="row">-->
        <!--<div class="col">-->
          <!--<h3>Сообщений нет</h3>-->
        <!--</div>-->
      <!--</div>-->
    <!--</div>-->
  </div>
</template>
<script>
  const DOMAIN = process.env.API_DOMAIN

  import socket from '@/plugins/socket.io'
  import { mapActions, mapGetters } from 'vuex'
  import api from '@/api'

  export default {
    middleware: 'authenticated',
    data () {
      return {
        chat_mob: false,
        contacts: true,
        tabs: {
          incoming: {
            active: true,
            title: 'Входящие'
          },
          systemic: {
            active: false,
            title: 'Системные'
          }
        },
        virtualUser: false,
        baseUrl: DOMAIN,
        show: false,
        tabUsers: [],
        chatUser: null,
        message: '',
        userId: null,
        test: null,
        img: '',
        check: false
      }
    },
    beforeMount () {
      this.getUserMessage()
      if (socket) {
        let base = this
        socket.on(this.userCurrent.id +':new-user-message', (message) => {
          base.setSocketMessage({
            sender_id: message.message.from_id,
            message: message.message.message
          })
          base.setMessageCount({
            user_id: message.message.from_id
            }
          )
          base.setUserUnreadMessage({
              count: this.userCurrent.unread_messages + 1
            }
          )
          this.scrollToBottom()
        })
      }
    },
    computed: {
      ...mapGetters({
        getContact: 'message/getContact',
        idUserMessage: 'message/id',
        userMessage: 'message/userMessage',
        chatMessage: 'message/chatMessage',
        userByIdMessage: 'message/userByIdMessage',
        userCurrent: 'user/user'
      }),
      activeTab () {
        let index = null
        if (this.idUserMessage !== null && this.userMessage !== [] && this.userMessage.users !== undefined) {
          const user = this.userMessage.users.find(users => users.id === this.idUserMessage)
          index = this.userMessage.users.indexOf(user)
        }
        return index
      }
    },
    methods: {
      ...mapActions({
        setUserUnreadMessage: 'user/setUserUnreadMessage',
        setUsers: 'message/setUsers',
        addUser: 'message/addUser',
        setMessageCount: 'message/setMessageCount',
        setUnread: 'message/setUnread',
        getUserMessage: 'message/getUserMessage',
        getChatMessage: 'message/getChatMessage',
        createMessage: 'message/createMessage',
        setStoreId: 'message/setStoreId',
        setSocketMessage: 'message/setSocketMessage'
      }),
      checkMessage (id) {
        if (this.idUserMessage !== null && this.userMessage !== [] && this.userMessage.users !== undefined){
          const user = this.userMessage.users.find(users => users.id === id)
          let index = this.userMessage.users.indexOf(user)
          if(index === this.activeTab || id === this.userCurrent.id)
            return true
          else
            return false
        }

      },
      chatBack () {
        this.chat_mob = true
        this.contacts = true
        console.log(123)
      },
      changeTab (index) {
        console.log(index)
        for (let key in this.tabs) {
          this.tabs[key].active = false
        }
        this.tabs[index].active = true
      },
      readMessage(id) {
        this.check = true
        const payload = {
          user_id: id
        }
        api.readMessage(payload)
          .then(() => {
            this.setUnread(payload)

          })
      },
      chengeTab(index, id) {
        if(window.innerWidth < 768) {
          this.chat_mob = false
        }
        console.log(index, id)
        this.readMessage(id)
        for (let key in this.userMessage.users) {
          this.tabUsers[key] = false
        }
        this.chatUser = this.userMessage.users[index]
        this.tabUsers[index] = true
        this.tabUsers.push()
        this.getChatMessage({
          user_id: id
        })
        this.setStoreId(id)
        this.userId = id
        this.scrollToBottom()
      },
      linkMessage (message) {
        let reg = /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9]\.[^\s]{2,})/
        let link = message.match(reg)
        let myMessage = message
        if(link){
          myMessage = message.replace(link[0], '<a href ="'+link[0]+ '">'+ link[0] + '</a>')
        }
        return myMessage
      },
      async onSendMessage() {
        if (this.message !== '' && this.userId > 0 || this.img !=='') {
          this.message = this.linkMessage(this.message)
          this.message = this.message + this.img
          const payload = {
            message: this.message,
            id: this.userId
          }
          console.log(payload)
          this.scrollToBottom()
          this.setSocketMessage({
            sender_id: this.userCurrent.id,
            message: payload.message
          })
          await this.createMessage(payload)
          this.message = ''
          this.img = ''
        }
      },
      scrollToBottom() {
        this.$nextTick(() => {
          let base = this
          setTimeout(() => {
            base.$refs.chatBody.getElementsByClassName('simplebar-scroll-content')[0].scrollTop = document.getElementById('message-container').scrollHeight
          }, 500)
          // console.log(document.getElementById('message-container').scrollHeight)
        })
      },
      uploadImg (e) {
        var file = e.target.files[0]
        const formData = new FormData()
        formData.append('image', file)
        api.loadImageChat(formData)
          .then(res => {
            //this.img = '<br>' +'<a href="' + DOMAIN + 'message-files/' + res.body.data  +'" target="_blank"><img class="load_img" src="'+ DOMAIN + 'message-files/' + res.body.data +'"></a>'
            this.img = '<br>' +'<div class="load_img_wrapper"><img class="load_img" src="'+ DOMAIN + 'message-files/' + res.body.data +'"></div>'
          })
      },
    },
    watch: {
      userMessage: {
        handler (val) {
          if(!this.check) {
            this.tabUsers = []
            if (val !== [] && this.userMessage) {
              if (this.activeTab !== null && this.idUserMessage !== null) {
                this.chengeTab(this.activeTab, this.idUserMessage)
              } else if (this.userMessage.count !== undefined) {
                this.chengeTab(0, this.userMessage.users[0].id)
              }

              if (val.users !== undefined) {
                this.virtualUser = true
                if(this.getContact){
                  if(!(val.users.find(user => user.id === this.getContact.id))){
                    const payload = this.getContact
                    this.addUser(payload)
                   // this.userIndex = this.userMessage.users.length - 1
                    this.chengeTab(this.userMessage.users.length - 1, this.getContact.id)
                  }
                  else{
                    let user = val.users.find(user => user.id === this.getContact.id)
                    this.userIndex = val.users.indexOf(user)
                    this.chengeTab(this.userIndex, this.userMessage.users[this.userIndex].id)
                  }
                }
                for (let key in val.users) {
                  let b = parseInt(key) === 0 ? true : false
                  this.tabUsers.push(b)
                }
                if(!this.getContact || !this.virtualUser) {
                  console.log(123)
                  this.chatUser = val.users[0]
                }
                else {
                  this.virtualUser = false
                }
              }
            }
          }
        },
        deep: true
      }
    }
  }
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

回答1:


Have you checked if some component needs to be wrapped in <no-ssr> tag?

We had similar issues where we had ssr: false in the config file for a library component

This worked in dev mode, but not in production.

We had to wrap the component in a <no-ssr> tag for the error to go away.



来源:https://stackoverflow.com/questions/54341251/render-function-or-template-not-defined-in-component-anonymous

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!