vue 2.0服務端渲染從零開始(二)

轉載:https://www.jianshu.com/p/bba6adef51cf

編寫通用代碼

編寫通用代碼時的約束條件:即運行在服務器和客戶端的代碼,因爲用例和平臺API的差別,當運行在不一樣環境中時,咱們的代碼將不會徹底相同。html

Vue.js 服務器端渲染指南--編寫通用代碼中詳細的介紹了須要注意的幾個方面:vue

  • 服務器上的數據響應
    • 獨立的應用程序實例
    • 禁用數據響應
  • 組件生命週期鉤子函數
    • 只有 beforeCreatecreate會在服務端渲染(SSR)過程當中被調用。
    • 反作用代碼移動到beforeMountmounted生命週期中。
  • 訪問特定平臺API
    • 僅瀏覽器可用的全局變量windowdocument,在純客戶端的生命週期鉤子函數中惰性訪問它們。
    • 儘量使用通用API,例如axios能夠向服務器和客戶端都暴露相同的API
  • 自定義指令
    • 推薦使用組件做爲抽象機制,並運行在「虛擬 DOM 層級(Virtual-DOM level)」(例如使用渲染函數render function)
    • 若是自定義指令不是很容易替換爲組件,則能夠在建立服務器renderer時,使用directives選項提供的"服務器端版本"

避免狀態單例

一樣是單例對象(vue實例),在純客戶端代碼時,vue實例在組件建立是生成,在組件銷燬後跟着從內存中清除。ios

可是Node.js服務器是一個長期運行的進程。建立的vue實例將一直留存在內存中,致使它被每一個傳入的請求共享,這樣很容易致使交叉請求狀態污染。express

所以,咱們不該該直接建立一個應用程序實例,而是應該暴露一個能夠重複執行的工廠函數,爲每一個請求建立新的應用程序實例。axios

工廠模式:
app.js瀏覽器

const Vue = require('vue')

module.exports = function createApp (context) {
  return new Vue({
    data: {
      url: context.url
    },
    template: '<div>訪問的 URL 是:{{ url }}</div>'
  })
}
複製代碼

server.jsbash

const createApp = require('./app')
  
 const app = createApp(context)
複製代碼
完整示例

const createApp = require('./app')
const server = require('express')();
const renderer = require('vue-server-renderer').createRenderer({
	template: require('fs').readFileSync('./app.template.html', 'utf-8')
});

server.get('*', (req, res) => {

  const context = {
	  title: '你好,VUE SSR!',
	  meta: `<meta name="description" content="Vue.js 服務端渲染指南">`,
	  url: req.url
	}
	
  const app = createApp(context)
  
  renderer.renderToString(app, context, (err, html) => {
    if (err) {
      res.status(500).end('Internal Server Error')
      return
    }
	res.setHeader('Content-Type','text/html;charset=UTF-8'); // 避免亂碼
    res.end(html)
  });
})

server.listen(8080, () =>{
	console.log('服務器啓動成功');
});
複製代碼


一樣的規則也適用於 router、store 和 event bus 實例。你不該該直接從模塊導出並將其導入到應用程序中,而是須要在 createApp 中建立一個新的實例,並從根 Vue 實例注入。
服務器

相關文章
相關標籤/搜索