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 相关文章推荐
jQuery 1.4 15个你应该知道的新特性(译)
Jan 24 Javascript
js实现温度计时间样式代码分享
Aug 21 Javascript
jquery-mobile基础属性与用法详解
Nov 23 Javascript
Bootstrap基本样式学习笔记之按钮(4)
Dec 07 Javascript
简单实现js悬浮导航效果
Feb 05 Javascript
vue 子组件向父组件传值方法
Feb 26 Javascript
angularjs http与后台交互的实现示例
Dec 21 Javascript
详解js动态获取浏览器或页面等容器的宽高
Mar 13 Javascript
Vue 如何使用props、emit实现自定义双向绑定的实现
Jun 05 Javascript
echarts饼图各个板块之间的空隙如何实现
Dec 01 Javascript
基于javascript实现放大镜特效
Dec 03 Javascript
typescript编写微信小程序创建项目的方法
Jan 29 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调用Webservice实例代码
2011/07/29 PHP
一个简单的php加密解密函数(动态加密)
2013/06/19 PHP
Android AsyncTack 异步任务实例详解
2016/11/02 PHP
PHP命名空间简单用法示例
2018/12/28 PHP
使用PHP反射机制来构造&quot;CREATE TABLE&quot;的sql语句
2019/03/21 PHP
PHP的Trait机制原理与用法分析
2019/10/18 PHP
Display SQL Server Version Information
2007/06/21 Javascript
【消息提示组件】,兼容IE6/7&amp;&amp;FF2
2007/09/04 Javascript
心扬JS分页函数代码
2010/09/10 Javascript
ExtJS 入门
2010/10/29 Javascript
jquery如何根据值设置默认的选中项
2014/03/17 Javascript
JS获得浏览器版本和操作系统版本的例子
2014/05/13 Javascript
node爬取微博的数据的简单封装库nodeweibo使用指南
2015/01/02 Javascript
JQuery中clone方法复制节点
2015/05/18 Javascript
javascript中加var和不加var的区别 你真的懂吗
2016/01/06 Javascript
js制作可以延时消失的菜单
2017/01/13 Javascript
详解vuex之store拆分即多模块状态管理(modules)篇
2018/11/13 Javascript
详解如何在vue项目中使用layui框架及采坑
2019/05/05 Javascript
vue App.vue中的公共组件改变值触发其他组件或.vue页面监听
2019/05/31 Javascript
vuex+axios+element-ui实现页面请求loading操作示例
2020/02/02 Javascript
使用Python3中的gettext模块翻译Python源码以支持多语言
2015/03/31 Python
Python实现确认字符串是否包含指定字符串的实例
2018/05/02 Python
Linux下python与C++使用dlib实现人脸检测
2018/06/29 Python
pytorch多进程加速及代码优化方法
2019/08/19 Python
Django 项目通过加载不同env文件来区分不同环境
2020/02/17 Python
Python模块/包/库安装的六种方法及区别
2020/02/24 Python
利用CSS3的3D效果制作正方体
2020/03/10 HTML / CSS
存储过程的优点有哪些
2012/09/27 面试题
集团薪酬管理制度
2014/01/13 职场文书
上课看小说检讨书
2014/02/22 职场文书
公务员群众路线心得体会
2014/11/03 职场文书
2014年宣传部工作总结
2014/11/12 职场文书
六一领导慰问欢迎词
2015/01/26 职场文书
推广普通话的宣传语
2015/07/13 职场文书
Oracle 区块链表创建过程详解
2021/05/15 Oracle
python脚本框架webpy模板控制结构
2021/11/20 Python