使用node+vue.js實現(xiàn)SPA應(yīng)用
業(yè)務(wù)需求
最近公司要求開發(fā)web版的app,由于app是偏向內(nèi)容方面,而且?guī)Я艘粋€聊天模塊,所以一般的多頁開發(fā)不是很適合,而且主要是手機瀏覽,對加載速度或者用戶體驗來說都比較苛刻。調(diào)研了很多框架和模式,最后自己東拼西湊搞出來了這么一個玩意。
服務(wù)端
毫無疑問使用node,使用typescript可以有效的在編碼同時查錯,強類型語言寫服務(wù)端毫無壓力。
#app.ts 只貼重要代碼 var webpack = require('webpack') var webpackDevMiddleware = require('webpack-dev-middleware') var WebpackConfig = require('./webpack.config') import * as index from "./routes/index"; import * as foo from "./routes/foo"; import * as bar from "./routes/bar"; var app = express(); //啟動服務(wù)的時候 打包并監(jiān)聽客戶端用到的文件,webpackDevMiddleware是開發(fā)模式,他會打包js在內(nèi)存里面,你改了文件,它也會重新打包 app.use(webpackDevMiddleware(webpack(WebpackConfig), { publicPath: '/__build__/', stats: { colors: true } })); //一般的配置項 app.set('views', __dirname + '/views'); app.set('view engine', 'ejs'); app.set('view options', { layout: false }); app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); app.use(methodOverride()); app.use(express.static(__dirname + '/public')); var env = process.env.NODE_ENV || 'development'; if (env === 'development') { app.use(errorHandler()); } //路由配置 app.get('/', index.index); app.get('/foo', foo.index); app.get('/bar', bar.index); app.listen(3000, function(){ console.log("Demo Express server listening on port %d in %s mode", 3000, app.settings.env); }); export var App = app;
服務(wù)端渲染頁面
#index.ts import express = require("express") import vueServer = require("vue-server") //服務(wù)端渲染vue的插件 var Vue = new vueServer.renderer(); //創(chuàng)建一個服務(wù)端的vue export function index(req: express.Request, res: express.Response) { //創(chuàng)建一個組件 var vm = new Vue({ template: ` <p>This is index!</p> ` }); //等待html渲染完成,再返回給瀏覽器 vueServer.htmlReady是vue-server的自帶事件 vm.$on('vueServer.htmlReady', function(html:string) { //這里用的是ejs模板 可以把需要用到的數(shù)據(jù)設(shè)置成window下的全局變量,方便客戶端的js訪問。 res.render('layout',{server_html:html,server_data:'window.cm_data = {name:"張三"}'}) }); };
#layout.ejs 訪問這個SPA的所有url返回的都是這個頁面 <meta>標簽都可以動態(tài)設(shè)置,只要傳參數(shù)進來就可以 <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Vue Router Example</title> <style> .v-link-active { color: red; } </style> <script> //定義一些前端需要用到的全局屬性,文章ID或用戶信息什么的 //index.ts中傳過來的是 window.cm_data = {name:"張三"} //前端就能訪問到了 <%-server_data%> </script> </head> <body> //這里的id是前端需要用到的一個標識 <div id="app"> <h1>Hello App!</h1> <p> <a v-link="{ path: '/foo' }">Go to Foo</a> <a v-link="{ path: '/bar' }">Go to Bar</a> </p> //router-view是客戶端vue-router需要解析的dom //server_html是根據(jù)訪問url地址生成的html,是做SEO的重點,不加載下面的app.js也可以看到內(nèi)容 <router-view> <%-server_html%> </router-view> </div> //webpack打包好的js,主要是路由配置 <script src="/__build__/app.js"></script> </body> </html>
客戶端
#app.js 這個是/__build__/app.js,可以用es6編寫,webpack會轉(zhuǎn)換的 import Vue from './vue.min' //客戶端的vue.js import VueRouter from './vue-router.min' //vue的路由插件,配合webpack可以很簡單實現(xiàn)懶加載 //懶加載路由 只有訪問這個路由才會加載js import Foo from 'bundle?lazy!../../components/foo' //配合webpack的bundle-loader,輕松實現(xiàn)懶加載 import Bar from 'bundle?lazy!../../components/bar' import Index from 'bundle?lazy!../../components/index' var App = Vue.extend({}) Vue.use(VueRouter) var router = new VueRouter({ //這里要好好說一下,一定要設(shè)置html5模式,不然前后端URL不統(tǒng)一會發(fā)生問題 //比如訪問 http://localhost:3000/ 服務(wù)端定義是訪問index.ts這個路由文件 //如果不是html5模式的話,經(jīng)過客戶端js運行之后會變成http://localhost:3000/#!/ //在比如直接瀏覽器輸入 http://localhost:3000/foo 服務(wù)端定義是訪問.ts這個路由文件 //如果不是html5模式的話,經(jīng)過客戶端js運行之后會變成 http://localhost:3000/foo/#!/ //設(shè)置了html5模式后,加載完js后不會加上#!這2個類似錨點的字符,實現(xiàn)前后端路由統(tǒng)一如果用戶刷新瀏覽器的話,服務(wù)端也能渲染出相應(yīng)的頁面。 history: true, //html5模式 去掉錨點 saveScrollPosition: true //記住頁面的滾動位置 html5模式適用 }) //定義路由,要和服務(wù)端路由路徑定義的一樣 router.map({ '/' : { component: Index //前端路由定義, }, '/foo': { component: Foo }, '/bar': { component: Bar } }) //啟動APP router.start(App, '#app')
需要完善的地方
前后端統(tǒng)一模板,已經(jīng)找到方法了把html分離出來,node端用fs.readFileSync方法獲取,客戶端用webpack的raw-loader獲取html內(nèi)容
不放源碼都是瞎扯。
源碼地址
相關(guān)文章
Node.js配合node-http-proxy解決本地開發(fā)ajax跨域問題
這篇文章主要介紹了Node.js配合node-http-proxy解決本地開發(fā)ajax跨域問題,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-08-08使用node-media-server搭建一個簡易的流媒體服務(wù)器
這篇文章主要介紹了使用node-media-server搭建一個簡易的流媒體服務(wù)器,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01export?default?和?export?的使用方式示例詳解
這篇文章主要介紹了export?default?和?export?的使用方式,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-08-08解決使用node命令提示:'node'不是內(nèi)部或外部命令,也不是可運行的程序
最近在工作中遇到了個常見的問題,分享給大家,這篇文章主要給大家介紹了關(guān)于如何解決使用node命令提示:'node'不是內(nèi)部或外部命令,也不是可運行的程序的相關(guān)資料,需要的朋友可以參考下2023-02-02