vue、react等单页面项目部署到服务器的方法及vue和react的区别


Posted in Javascript onSeptember 29, 2018

最近好多伙伴说,我用vue做的项目本地是可以的,但部署到服务器遇到好多问题:资源找不到,直接访问index.html页面空白,刷新当前路由404。。。用react做的项目也同样遇到类似问题。现在我们一起讨论下单页面如何部署到服务器?

由于前端路由缘故,单页面应用应该放到nginx或者apache、tomcat等web代理服务器中,千万不要直接访问index.html,同时要根据自己服务器的项目路径更改react或vue的路由地址。

如果说项目是直接跟在域名后面的,比如:http://www.sosout.com ,根路由就是 '/'。
如果说项目是直接跟在域名后面的一个子目录中的,比如: http://www.sosout.com/children  ,根路由就是 '/children ',不能直接访问index.html。

以配置Nginx为例,配置过程大致如下:(假设:

1、项目文件目录: /mnt/html/spa(spa目录下的文件就是执行了npm run dist 后生成的dist目录下的文件)

2、访问域名:spa.sosout.com)

进入nginx.conf新增如下配置:

server {
 listen 80;
 server_name spa.sosout.com;
 root /mnt/html/spa;
 index index.html;
 location ~ ^/favicon\.ico$ {
 root /mnt/html/spa;
 }

 location / {
 try_files $uri $uri/ /index.html;
 proxy_set_header Host  $host;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_set_header X-Forwarded-Proto $scheme;
 }
 access_log /mnt/logs/nginx/access.log main;
}

注意事项:

1、配置域名的话,需要80端口,成功后,只要访问域名即可访问的项目
2、如果你使用了react-router的 browserHistory 模式或 vue-router的 history 模式,在nginx配置还需要重写路由:

server {
 listen 80;
 server_name spa.sosout.com;
 root /mnt/html/spa;
 index index.html;
 location ~ ^/favicon\.ico$ {
 root /mnt/html/spa;
 }

 location / {
 try_files $uri $uri/ @fallback;
 index index.html;
 proxy_set_header Host  $host;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_set_header X-Forwarded-Proto $scheme;
 }
 location @fallback {
 rewrite ^.*$ /index.html break;
 }
 access_log /mnt/logs/nginx/access.log main;
}

为什么要重写路由?因为我们的项目只有一个根入口,当输入类似/home的url时,如果找不到对应的页面,nginx会尝试加载index.html,这是通过react-router或vue-router就能正确的匹配我们输入的/home路由,从而显示正确的home页面,如果browserHistory模式或history模式的项目没有配置上述内容,会出现404的情况。

简单举两个例子,一个vue项目一个react项目:

vue项目:

域名:http://tb.sosout.com

vue、react等单页面项目部署到服务器的方法及vue和react的区别

############
# 其他配置
############

http {
 ############
 # 其他配置
 ############
 server {
 listen 80;
 server_name tb.sosout.com;
 root /mnt/html/tb;
 index index.html;
 location ~ ^/favicon\.ico$ {
  root /mnt/html/tb;
 }
 
 location / {
  try_files $uri $uri/ @fallback;
  index index.html;
  proxy_set_header Host  $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
 }
 location @fallback {
  rewrite ^.*$ /index.html break;
 }
 access_log /mnt/logs/nginx/access.log main;
 }
 ############
 # 其他配置
 ############ 
}

vue、react等单页面项目部署到服务器的方法及vue和react的区别

import App from '../App'

// 首页
const home = r => require.ensure([], () => r(require('../page/home/index')), 'home')

// 物流
const logistics = r => require.ensure([], () => r(require('../page/logistics/index')), 'logistics')

// 购物车
const cart = r => require.ensure([], () => r(require('../page/cart/index')), 'cart')

// 我的
const profile = r => require.ensure([], () => r(require('../page/profile/index')), 'profile')

// 登录界面
const login = r => require.ensure([], () => r(require('../page/user/login')), 'login')

export default [{
 path: '/',
 component: App, // 顶层路由,对应index.html
 children: [{
 path: '/home', // 首页
 component: home
 }, {
 path: '/logistics', // 物流
 component: logistics,
 meta: {
 login: true
 }
 }, {
 path: '/cart', // 购物车
 component: cart,
 meta: {
 login: true
 }
 }, {
 path: '/profile', // 我的
 component: profile
 }, {
 path: '/login', // 登录界面
 component: login
 }, {
 path: '*',
 redirect: '/home'
 }]
}]

react项目:

域名:http://antd.sosout.com

vue、react等单页面项目部署到服务器的方法及vue和react的区别

/**
* 疑惑一:
* React createClass 和 extends React.Component 有什么区别?
* 之前写法:
* let app = React.createClass({
* getInitialState: function(){
* // some thing
* }
* })
* ES6写法(通过es6类的继承实现时state的初始化要在constructor中声明):
* class exampleComponent extends React.Component {
* constructor(props) {
* super(props);
* this.state = {example: 'example'}
* }
* }
*/

import React, {Component, PropTypes} from 'react'; // react核心
import { Router, Route, Redirect, IndexRoute, browserHistory, hashHistory } from 'react-router'; // 创建route所需
import Config from '../config/index';
import layout from '../component/layout/layout'; // 布局界面

import login from '../containers/login/login'; // 登录界面

/**
 * (路由根目录组件,显示当前符合条件的组件)
 * 
 * @class Roots
 * @extends {Component}
 */
class Roots extends Component {
 render() {
 // 这个组件是一个包裹组件,所有的路由跳转的页面都会以this.props.children的形式加载到本组件下
 return (
  <div>{this.props.children}</div>
 );
 }
}

// const history = process.env.NODE_ENV !== 'production' ? browserHistory : hashHistory;

// 快速入门
const home = (location, cb) => {
 require.ensure([], require => {
 cb(null, require('../containers/home/homeIndex').default)
 }, 'home');
}

// 百度图表-折线图
const chartLine = (location, cb) => {
 require.ensure([], require => {
 cb(null, require('../containers/charts/lines').default)
 }, 'chartLine');
}

// 基础组件-按钮
const button = (location, cb) => {
 require.ensure([], require => {
 cb(null, require('../containers/general/buttonIndex').default)
 }, 'button');
}

// 基础组件-图标
const icon = (location, cb) => {
 require.ensure([], require => {
 cb(null, require('../containers/general/iconIndex').default)
 }, 'icon');
}

// 用户管理
const user = (location, cb) => {
 require.ensure([], require => {
 cb(null, require('../containers/user/userIndex').default)
 }, 'user');
}

// 系统设置
const setting = (location, cb) => {
 require.ensure([], require => {
 cb(null, require('../containers/setting/settingIndex').default)
 }, 'setting');
}

// 广告管理
const adver = (location, cb) => {
 require.ensure([], require => {
 cb(null, require('../containers/adver/adverIndex').default)
 }, 'adver');
}

// 组件一
const oneui = (location, cb) => {
 require.ensure([], require => {
 cb(null, require('../containers/ui/oneIndex').default)
 }, 'oneui');
}

// 组件二
const twoui = (location, cb) => {
 require.ensure([], require => {
 cb(null, require('../containers/ui/twoIndex').default)
 }, 'twoui');
}

// 登录验证
const requireAuth = (nextState, replace) => {
 let token = (new Date()).getTime() - Config.localItem('USER_AUTHORIZATION');
 if(token > 7200000) { // 模拟Token保存2个小时
 replace({
  pathname: '/login',
  state: { nextPathname: nextState.location.pathname }
 });
 }
}

const RouteConfig = (
 <Router history={browserHistory}>
 <Route path="/home" component={layout} onEnter={requireAuth}>
  <IndexRoute getComponent={home} onEnter={requireAuth} /> // 默认加载的组件,比如访问www.test.com,会自动跳转到www.test.com/home
  <Route path="/home" getComponent={home} onEnter={requireAuth} />
  <Route path="/chart/line" getComponent={chartLine} onEnter={requireAuth} />
  <Route path="/general/button" getComponent={button} onEnter={requireAuth} />
  <Route path="/general/icon" getComponent={icon} onEnter={requireAuth} />
  <Route path="/user" getComponent={user} onEnter={requireAuth} />
  <Route path="/setting" getComponent={setting} onEnter={requireAuth} />
  <Route path="/adver" getComponent={adver} onEnter={requireAuth} />
  <Route path="/ui/oneui" getComponent={oneui} onEnter={requireAuth} />
  <Route path="/ui/twoui" getComponent={twoui} onEnter={requireAuth} />
 </Route>
 <Route path="/login" component={Roots}> // 所有的访问,都跳转到Roots
  <IndexRoute component={login} /> // 默认加载的组件,比如访问www.test.com,会自动跳转到www.test.com/home
 </Route>
 <Redirect from="*" to="/home" />
 </Router>
);

export default RouteConfig;

vue、react等单页面项目部署到服务器的方法及vue和react的区别

############
# 其他配置
############

http {
 ############
 # 其他配置
 ############
 server {
 listen 80;
 server_name antd.sosout.com;
 root /mnt/html/reactAntd;
 index index.html;
 location ~ ^/favicon\.ico$ {
  root /mnt/html/reactAntd;
 }
 location / {
  try_files $uri $uri/ @router;
  index index.html;
  proxy_set_header Host  $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
 }
 location @router {
  rewrite ^.*$ /index.html break;
 }
 access_log /mnt/logs/nginx/access.log main;
 }
 ############
 # 其他配置
 ############ 
}

下面看下vue和react区别

前端都知道3个主流框架,vue,react,anjular,当然目前最火的还是vue和react,那么vue 和react 的区别?

相同点:

    1.都支持服务器端渲染

    2.都有Virtual DOM,组件化开发,通过props参数进行父子组件数据的传递,都实现webComponent规范

    3.数据驱动视图

    4.都有支持native的方案,React的React native,Vue的weex

    5.都有管理状态,React有redux,Vue有自己的Vuex(自适应vue,量身定做)

不同点:

       1.React严格上只针对MVC的view层,Vue则是MVVM模式

       2.virtual DOM不一样,vue会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树.

           而对于React而言,每当应用的状态被改变时,全部组件都会重新渲染,所以react中会需要shouldComponentUpdate这个生命周期函数方法来进行控制

       3.组件写法不一样, React推荐的做法是 JSX + inline style, 也就是把HTML和CSS全都写进JavaScript了,即'all in js';

           Vue推荐的做法是webpack+vue-loader的单文件组件格式,即html,css,jd写在同一个文件;

       4.数据绑定: vue实现了数据的双向绑定,react数据流动是单向的

       5.state对象在react应用中不可变的,需要使用setState方法更新状态;

         在vue中,state对象不是必须的,数据由data属性在vue对象中管理;

就对我而言吧,vue适合开发移动端项目,react适合开发pc端项目(个人观点),

              当然我还是喜欢 React,毕竟后台大,哈哈,虽然现在升级到16版本了(不喜勿喷)

总结

以上所述是小编给大家介绍的vue、react等单页面项目应用部署到服务器的方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
js变量作用域及可访问性的探讨
Nov 23 Javascript
在一个form用一个SUBMIT(或button)分别提交到两个处理表单页面的代码
Feb 15 Javascript
JS+CSS制作DIV层可(最小化/拖拽/排序)功能实现代码
Feb 25 Javascript
Js操作树节点自动折叠展开的几种方法
May 05 Javascript
一张表格告诉你windows.onload()与$(document).ready()的区别
May 16 Javascript
JavaScript Serializer序列化时间处理示例
Jul 31 Javascript
谈谈encodeURI和encodeURIComponent以及escape的区别与应用
Nov 24 Javascript
jquery中validate与form插件提交的方式小结
Mar 26 Javascript
bootstrap网格系统使用方法解析
Jan 13 Javascript
jQuery中Chosen三级联动功能实例代码
Mar 07 Javascript
详解Bootstrap 学习(一)入门
Apr 12 Javascript
vue调用语音播放的方法
Sep 27 Javascript
浅谈针对Vue相同路由不同参数的刷新问题
Sep 29 #Javascript
vue init webpack 建vue项目报错的解决方法
Sep 29 #Javascript
详解React之key的使用和实践
Sep 29 #Javascript
vue给组件传递不同的值方法
Sep 29 #Javascript
vue动画之点击按钮往上渐渐显示出来的实例
Sep 29 #Javascript
浅谈vue项目打包优化策略
Sep 29 #Javascript
vue里input根据value改变背景色的实例
Sep 29 #Javascript
You might like
利用PHP制作简单的内容采集器的原理分析
2008/10/01 PHP
如何使用Linux的Crontab定时执行PHP脚本的方法
2011/12/19 PHP
一个漂亮的php验证码类(分享)
2013/08/06 PHP
Composer设置忽略版本匹配的方法
2016/04/27 PHP
PHP封装返回Ajax字符串和JSON数组的方法
2017/02/17 PHP
javascript编程起步(第五课)
2007/02/27 Javascript
20款非常优秀的 jQuery 工具提示插件 推荐
2012/07/15 Javascript
js实时获取系统当前时间实例代码
2013/06/28 Javascript
js计算字符串长度包含的中文是utf8格式
2013/10/15 Javascript
JavaScript弹出新窗口后向父窗口输出内容的方法
2015/04/06 Javascript
chrome不支持form.submit的解决方案
2015/04/28 Javascript
jquery对dom节点的操作【推荐】
2016/04/15 Javascript
js实现动态创建的元素绑定事件
2016/07/19 Javascript
jquery  实现轮播图详解及实例代码
2016/10/12 Javascript
jQuery实现html table行Tr的复制、删除、计算功能
2017/07/10 jQuery
仿京东快报向上滚动的实例
2017/12/13 Javascript
VUE 实现滚动监听 导航栏置顶的方法
2018/09/11 Javascript
使用electron将vue-cli项目打包成exe的方法
2018/09/29 Javascript
详解使用Nuxt.js快速搭建服务端渲染(SSR)应用
2019/03/13 Javascript
js中!和!!的区别与用法
2020/05/09 Javascript
[02:24]DOTA2亚洲邀请赛 NAVI战队出场宣传片
2015/02/07 DOTA
Python脚本实现格式化css文件
2015/04/08 Python
Python3连接MySQL(pymysql)模拟转账实现代码
2016/05/24 Python
python将excel转换为csv的代码方法总结
2019/07/03 Python
python中update的基本使用方法详解
2019/07/17 Python
使用Python实现正态分布、正态分布采样
2019/11/20 Python
Django用户认证系统如何实现自定义
2020/11/12 Python
使用索引有什么好处
2016/07/27 面试题
大型营销活动计划书
2014/04/28 职场文书
公安纪律作风整顿剖析材料
2014/10/10 职场文书
2014年酒店工作总结与计划
2014/11/17 职场文书
运动会开幕式新闻稿
2015/07/17 职场文书
2015年卫生局工作总结
2015/07/24 职场文书
2016年“5.12”护士节慰问信
2015/11/30 职场文书
2019年入党思想汇报格式与要求
2019/06/25 职场文书
浅谈python中的多态
2021/06/15 Python