使用node+vue.js实现SPA应用

业务需求

最近公司要求开发web版的app,由于app是偏向内容方面,而且带了一个聊天模块,所以一般的多页开发不是很适合,而且主要是手机浏览,对加载速度或者用户体验来说都比较苛刻。调研了很多框架和模式,最后自己东拼西凑搞出来了这么一个玩意。

服务端

毫无疑问使用node,使用typescript可以有效的在编码同时查错,强类型语言写服务端毫无压力。

#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();

//启动服务的时候 打包并监听客户端用到的文件,webpackDevMiddleware是开发模式,他会打包js在内存里面,你改了文件,它也会重新打包
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;

服务端渲染页面

#index.ts
import express = require("express")
import vueServer = require("vue-server") //服务端渲染vue的插件

var Vue = new vueServer.renderer(); //创建一个服务端的vue

export function index(req: express.Request, res: express.Response) {

  //创建一个组件
  var vm = new Vue({
    template: `
    <p>This is index!</p>
    `
  });

  //等待html渲染完成,再返回给浏览器 vueServer.htmlReady是vue-server的自带事件
  vm.$on('vueServer.htmlReady', function(html:string) {
    //这里用的是ejs模板 可以把需要用到的数据设置成window下的全局变量,方便客户端的js访问。
    res.render('layout',{server_html:html,server_data:'window.cm_data = {name:"张三"}'})
  });

};
#layout.ejs 访问这个SPA的所有url返回的都是这个页面 <meta>标签都可以动态设置,只要传参数进来就可以
<!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是根据访问url地址生成的html,是做SEO的重点,不加载下面的app.js也可以看到内容
  <router-view> <%-server_html%> </router-view>
</div>
//webpack打包好的js,主要是路由配置
<script src="/__build__/app.js"></script>
</body>
</html>

客户端

#app.js 这个是/__build__/app.js,可以用es6编写,webpack会转换的

import Vue from './vue.min' //客户端的vue.js
import VueRouter from './vue-router.min' //vue的路由插件,配合webpack可以很简单实现懒加载

//懒加载路由 只有访问这个路由才会加载js
import Foo from 'bundle?lazy!../../components/foo' //配合webpack的bundle-loader,轻松实现懒加载
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({
  //这里要好好说一下,一定要设置html5模式,不然前后端URL不统一会发生问题
  //比如访问 http://localhost:3000/ 服务端定义是访问index.ts这个路由文件
  //如果不是html5模式的话,经过客户端js运行之后会变成http://localhost:3000/#!/

  //在比如直接浏览器输入 http://localhost:3000/foo 服务端定义是访问.ts这个路由文件
  //如果不是html5模式的话,经过客户端js运行之后会变成 http://localhost:3000/foo/#!/

  //设置了html5模式后,加载完js后不会加上#!这2个类似锚点的字符,实现前后端路由统一如果用户刷新浏览器的话,服务端也能渲染出相应的页面。
  history: true, //html5模式 去掉锚点
  saveScrollPosition: true //记住页面的滚动位置 html5模式适用
})

//定义路由,要和服务端路由路径定义的一样
router.map({
  '/'  : {
    component: Index //前端路由定义,
  },
  '/foo': {
    component: Foo
  },
  '/bar': {
    component: Bar
  }
})

//启动APP
router.start(App, '#app')

需要完善的地方

前后端统一模板,已经找到方法了把html分离出来,node端用fs.readFileSync方法获取,客户端用webpack的raw-loader获取html内容

不放源码都是瞎扯。

源码地址

https://github.com/yjj5855/node-vue-server-webpack

(0)

相关推荐

  • Vue Spa切换页面时更改标题的实例代码

    在Vue组件化开发过程中,因为是单页面开发,但是有时候需要页面的title根据情况改变,于是上网查了一下,各种说法花(wo)里(kan)胡(bu)哨(dong), 于是想到一个黑科技 documet.title="xxx"; 随便创建一个项目,在独立的模块中,created在钩子函数启动之后document.title='标题'; 但是据说在IOS的微信下是无效的,虽然用苹果机测试过有用,但是想到这样会影响我的代码洁癖. <script> export default {

  • vue路由嵌套的SPA实现步骤

    本文为大家分享了路由嵌套的SPA实现的步骤: A(/a)组件需要嵌套B组件(/b)和C组件(/c) ①准备嵌套其它组价的父组件 指定一个容器 在A组件指定一个容器 <router-view></router-ivew> ②在A组件的路由配置对象中指定children属性 { path:'/a', component:A, children:[ {path:'/b',component:B}, {path:'/c',component:C}, ] } 补充: //数字如果超出记录的次

  • Vue.js实现一个SPA登录页面的过程【推荐】

    技术栈 vue.js 主框架 vuex 状态管理 vue-router 路由管理 一般过程 在一般的登录过程中,一种前端方案是: 检查状态:进入页面时或者路由变化时检查是否有登录状态(保存在cookie或者本地存储的值): 如果有登录态则查询登录信息(uid,头像等...)并保存起来:如果没有则跳转到登录页: 在登录页面(或者登录框),校检用户输入信息是否合法: 校检通过后发送登录请求:校检不成功则反馈给用户: 登录成功则从后端数据中取出session信息保存登录状态(可能需要跳转);登录不成功

  • vue中SPA单页面应用程序详解

    一.SPA的概述 SPA(single page application)单页面应用程序,在一个完成的应用或者站点中,只有一个完整的html页面,这个页面有一个容器,可以把需要加载的代码片段插入到该容器中. SPA的工作原理: eg:  http://127.0.0.1/index.html#/start ①根据地址栏中url解析完整的页面:index.html 加载index.html ②根据地址栏中url解析#后的路由地址: start 根据路由地址,去在当前应用的配置中 找该路由地址的配置

  • 使用node+vue.js实现SPA应用

    业务需求 最近公司要求开发web版的app,由于app是偏向内容方面,而且带了一个聊天模块,所以一般的多页开发不是很适合,而且主要是手机浏览,对加载速度或者用户体验来说都比较苛刻.调研了很多框架和模式,最后自己东拼西凑搞出来了这么一个玩意. 服务端 毫无疑问使用node,使用typescript可以有效的在编码同时查错,强类型语言写服务端毫无压力. #app.ts 只贴重要代码 var webpack = require('webpack') var webpackDevMiddleware =

  • 使用Vue.js创建一个时间跟踪的单页应用

    Vue.js很简单.正因为如此简单,人们常常认为其适合于小项目.虽然真正的Vue.js核心知识只是一个视图层库,实际上有一组工具,将使您能够使用Vue.js构建完整的大规模SPA(单页应用程序). SPA应用可以在不完全重新加载网页,产生一个更流畅的用户体验到的用户交互响应.还有好的副作用,SPA还鼓励后端专注于展示数据端点,这使得整体架构更加分离,并且对于其他类型的客户端可能是可重用的. 从开发人员的角度来看,SPA和传统的后端呈现应用程序之间的主要区别是,我们必须将客户端视为具有自己架构的应

  • 利用Vue.js+Node.js+MongoDB实现一个博客系统(附源码)

    前言 这篇文章实现的博客系统使用 Vue 做前端框架,Node + express 做后端,数据库使用的是 MongoDB.实现了用户注册.用户登录.博客管理(文章的修改和删除).文章编辑(Markdown).标签分类等功能. 前端模仿的是 hexo 的经典主题 NexT,本来是想把源码直接拿过来用的,后来发现还不如自己写来得快,就全部自己动手实现成 vue components. 实现的功能 1.文章的编辑,修改,删除 2.支持使用 Markdown 编辑与实时预览 3.支持代码高亮 4.给文

  • 超简单的Vue.js环境搭建教程

    vue这个新的工具,确实能够提高效率,vue入门的精髓:(前提都是在网络连接上的情况下) 1.要使用vue来开发前端框架,首先要有环境,这个环境要借助于node,所以要先安装node,借助于node里面的npm来安装需要的依赖等等. 这里有一个小技巧:如果在cmd中直接使用npm来安装的一些工具的话会比较慢,所以我们使用淘宝的npm镜像: 输入npm install -g cnpm –registry=https://registry.npm.taobao.org,即可安装npm镜像,以后再用到

  • 使用 vue.js 构建大型单页应用

    前置条件: 熟悉使用 Javascript + HTML5 + css3. 理解 ES2015 Module 模块(export.import.export-default). 了解 nodejs 基础知识,npm 常用命令,以及 npm script 使用 (vue 项目中使用 npm 进行包管理). 了解 webpack 打包工具 (常用配置选项以及 loader 概念).(webpack webpack.github.io/ 是一个模块打包工具.它将一堆文件中的每个文件都作为一个模块,找出

  • 使用Vue.js和Flask来构建一个单页的App的示例

    在这个教程中,我们将讲解如何将vue.js单页应用与Flask后端进行连接. 一般来说,如果你只是想通过Flask模板使用vue.js库也是没有问题的.但是,实际上是一个很明显的问题那就是,Jinja(模板引擎)也和Vue.js一样采用双大括号用于渲染,但只是一个还算过的去的解决方案. 我想要一个不同的例子.如果我需要建立一个单页应用程序(应用程序使用单页组成, vue-router 在HTML5的History-mode以及其他更多好用的功能)用vue.js,由Flask提供Web服务?简单地

  • Vue.js 2.5新特性介绍(推荐)

    TypeScript TypeScript是一种由微软开发的自由和开源的编程语言.它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程.2012年十月份,微软发布了首个公开版本的TypeScript,在2013年6月19日,微软发布了TypeScript 0.9的正式版本,到目前为止,TypeScript已发展到2.x版本 安装TypeScript 安装TypeScript主要有两种方式: 通过npm方式安装(Node.js包管理器) 安装TypeS

  • 详解基于 Nuxt 的 Vue.js 服务端渲染实践

    Vue.js 是目前最火热的前端框架之一,而 Nuxt.js 是针对 Vue.js 推出的服务端渲染框架,通过高度定制化的配置以及简洁的 API,开发者可以快速进行服务端渲染项目的开发,本文将对 Nuxt.js 框架做一个简要介绍. 服务端渲染 服务端渲染(Server Side Render)并不是一个新的概念,在单页应用(SPA)还没有流行起来的时候,页面就是通过服务端渲染好,并传递给浏览器的.当用户需要访问新的页面时,需要再次请求服务器,返回新的页面. 为了优化体验,开发者们开始选择采用

  • Vue.js每天必学之组件与组件间的通信

    什么是组件? 组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能.在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展. 使用组件 注册 之前说过,我们可以用 Vue.extend() 创建一个组件构造器: var MyComponent = Vue.extend({ // 选项... }) 要把这个构造器用作组件,需要用 `Vue.compone

随机推荐