2017-04-08 19 views
10

Tôi đang cố gắng tạo ngăn xếp bằng cách sử dụng Hiển thị phía máy chủ (SSR) và Loại bản ghi. Mọi thứ đều ổn nhưng tôi gặp lỗi: TypeError: Cannot read property 'render' of undefined. Đây là ngăn xếp đầy đủ dấu vết:VueJs: Lỗi khi hiển thị phía máy chủ và Loại bản ghi

TypeError: Cannot read property 'render' of undefined 
    at normalizeRender (/Users/shoun/Documents/repositories/vuejs-ssr-typescript/node_modules/vue-server-renderer/build.js:6621:19) 
    at render (/Users/shoun/Documents/repositories/vuejs-ssr-typescript/node_modules/vue-server-renderer/build.js:6840:5) 
    at Object.renderToString (/Users/shoun/Documents/repositories/vuejs-ssr-typescript/node_modules/vue-server-renderer/build.js:6871:9) 
    at /Users/shoun/Documents/repositories/vuejs-ssr-typescript/dist/server.js:16:14 
    at Layer.handle [as handle_request] (/Users/shoun/Documents/repositories/vuejs-ssr-typescript/node_modules/express/lib/router/layer.js:95:5) 
    at next (/Users/shoun/Documents/repositories/vuejs-ssr-typescript/node_modules/express/lib/router/route.js:137:13) 
    at Route.dispatch (/Users/shoun/Documents/repositories/vuejs-ssr-typescript/node_modules/express/lib/router/route.js:112:3) 
    at Layer.handle [as handle_request] (/Users/shoun/Documents/repositories/vuejs-ssr-typescript/node_modules/express/lib/router/layer.js:95:5) 
    at /Users/shoun/Documents/repositories/vuejs-ssr-typescript/node_modules/express/lib/router/index.js:281:22 
    at param (/Users/shoun/Documents/repositories/vuejs-ssr-typescript/node_modules/express/lib/router/index.js:354:14) 
TypeError: Cannot read property 'render' of undefined 
    at normalizeRender (/Users/shoun/Documents/repositories/vuejs-ssr-typescript/node_modules/vue-server-renderer/build.js:6621:19) 
    at render (/Users/shoun/Documents/repositories/vuejs-ssr-typescript/node_modules/vue-server-renderer/build.js:6840:5) 
    at Object.renderToString (/Users/shoun/Documents/repositories/vuejs-ssr-typescript/node_modules/vue-server-renderer/build.js:6871:9) 
    at /Users/shoun/Documents/repositories/vuejs-ssr-typescript/dist/server.js:16:14 
    at Layer.handle [as handle_request] (/Users/shoun/Documents/repositories/vuejs-ssr-typescript/node_modules/express/lib/router/layer.js:95:5) 
    at next (/Users/shoun/Documents/repositories/vuejs-ssr-typescript/node_modules/express/lib/router/route.js:137:13) 
    at Route.dispatch (/Users/shoun/Documents/repositories/vuejs-ssr-typescript/node_modules/express/lib/router/route.js:112:3) 
    at Layer.handle [as handle_request] (/Users/shoun/Documents/repositories/vuejs-ssr-typescript/node_modules/express/lib/router/layer.js:95:5) 
    at /Users/shoun/Documents/repositories/vuejs-ssr-typescript/node_modules/express/lib/router/index.js:281:22 
    at param (/Users/shoun/Documents/repositories/vuejs-ssr-typescript/node_modules/express/lib/router/index.js:354:14) 

Dưới đây là cấu hình máy chủ của tôi:

import * as express from 'express'; 
import * as path from 'path'; 
import * as VueRender from 'vue-server-renderer'; 
import * as fs from 'fs-extra'; 
import app from './assets/app'; 
declare var __dirname; 

// Get the HTML layout 
const layout = fs.readFileSync(path.join(__dirname, 'index.html'), 'utf8'); 

// Create a renderer 
const renderer = VueRender.createRenderer(); 

let server = express(); 

server.get('/hello', function (req, res) { 
    res.send('Hello World!'); 
}); 

server.use('/assets', express.static(path.join(__dirname, 'assets'))); 

// Handle all GET requests 
server.get('*', function (request, response) { 
    // Render our Vue app to a string 
    renderer.renderToString(
     // Create an app instance 
     app(), 
     // Handle the rendered result 
     function (error, html) { 
      // If an error occurred while rendering... 
      if (error) { 
       // Log the error in the console 
       console.error(error); 
       // Tell the client something went wrong 
       return response 
        .status(500) 
        .send('Server Error') 
      } 
      // Send the layout with the rendered app's HTML 
      response.send(layout.replace('<div id="app"></div>', html)) 
     } 
    ) 
}); 

let port = 4500; 
server.listen(port,() => { 
    console.log(`App listening on ${port}`); 
}); 

Bạn có thể tìm mã nguồn trên kho github của tôi: https://github.com/sichida/vuejs-ssr-typescript. Tôi thực sự có thể sử dụng một số trợ giúp vì tôi bị kẹt ...

Cảm ơn bạn rất nhiều!

Trả lời

1

Tôi đã kiểm tra repo của bạn và vấn đề thực sự là trong file src/assets/app.ts, trong createApp chức năng bạn đang trở về một đối tượng kiểu ComponentOptions nhưng renderToString mất một đối tượng kiểu Vue.

Nó thực sự có thể được đơn giản hơn nhiều so với những gì bạn có ngay bây giờ:

import * as Vue from 'vue'; 

let createApp = function() { 
    return new Vue({ 
    props: ['message'], 
    template: '<span>{{ message }}</span>', 
    }); 
}; 
export default createApp; 

Và đó là nó, bạn chỉ cần phải trả lại một Vue dụ mới.

1

Những gì tôi đã tìm thấy rằng để cho Vue để render một cái gì đó, nó cần một trong số này:

  • render tài sản
  • template tài sản
  • $mount() ed

N ow nếu bạn đang như tôi, và bạn có một cái gì đó như thế này trong HTML của bạn:

<div id="app"> 
    <navbar></navbar> 
    ... 
</div> 

và sử dụng để gắn kết nó như app.$mount('#app'), những gì bạn cần làm là:

  • Move <div id="app"> hoàn toàn với nội dung của nó cho một thành phần (có thể gọi nó là App.vue?)
  • Thêm một tài sản render vào ví dụ Vue như render: h => h(App) nơi App là thành phần bạn vừa tạo
  • Sử dụng thành phần trực tiếp cho SSR, ví dụ: trả lại từ entry-server.js của bạn hoặc bất cứ điều gì
  • Do $mount rằng dụ trong entry-client.js cho hydrat hóa
Các vấn đề liên quan