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提交form表单时禁止重复提交的方法
Feb 13 Javascript
JavaScript定义类和对象的方法
Nov 26 Javascript
微信小程序使用第三方库Immutable.js实例详解
Sep 27 Javascript
jquery移除了live()、die(),新版事件绑定on()、off()的方法
Oct 26 Javascript
利用pm2部署多个node.js项目的配置教程
Oct 22 Javascript
深入理解vue中slot与slot-scope的具体使用
Jan 26 Javascript
Vue 中的compile操作方法
Feb 26 Javascript
vue 自定义提示框(Toast)组件的实现代码
Aug 17 Javascript
vue router 用户登陆功能的实例代码
Apr 24 Javascript
vue 子组件watch监听不到prop的解决
Aug 09 Javascript
Vue 实现拨打电话操作
Nov 16 Javascript
js之ajax文件上传
May 13 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
启用Csrf后POST数据时出现的400错误
2015/07/05 PHP
PHP函数引用返回的实例详解
2016/09/11 PHP
php传值和传引用的区别点总结
2019/11/19 PHP
基于PHP+Mysql简单实现了图书购物车系统的实例详解
2020/08/06 PHP
论坛里点击别人帖子下面的回复,回复标题变成“回复 24# 的帖子”
2009/06/14 Javascript
javascript的onchange事件与jQuery的change()方法比较
2009/09/28 Javascript
Jquery cookie操作代码
2010/03/14 Javascript
JavaScript实现页面滚动图片加载(仿lazyload效果)
2011/07/22 Javascript
jQuery探测位置的提示弹窗(toolTip box)详细解析
2013/11/14 Javascript
封装的jquery翻页滚动(示例代码)
2013/11/18 Javascript
javascript 按键事件(兼容各浏览器)
2013/12/20 Javascript
js 验证身份证信息有效性
2014/03/28 Javascript
JavaScript实现数据类型的相互转换
2016/03/06 Javascript
正则验证小数点后面只能有两位数的方法
2017/02/28 Javascript
node.js 中间件express-session使用详解
2017/05/20 Javascript
基于layer.js实现收货地址弹框选择然后返回相应的地址信息
2017/05/26 Javascript
Nodejs实现多房间简易聊天室功能
2017/06/20 NodeJs
vue项目中使用axios上传图片等文件操作
2017/11/02 Javascript
使用vue-cli webpack 快速搭建项目的代码
2018/11/21 Javascript
NodeJs操作MongoDB教程之分页功能以及常见问题
2019/04/09 NodeJs
详解VUE项目中安装和使用vant组件
2019/04/28 Javascript
搭建一个Koa后端项目脚手架的方法步骤
2019/05/30 Javascript
深入了解query和params的使用区别
2019/06/24 Javascript
微信小程序引入模块中wxml、wxss、js的方法示例
2019/08/09 Javascript
js中console在一行内打印字符串和对象的方法
2019/09/10 Javascript
实例解析Python中的__new__特殊方法
2016/06/02 Python
浅谈Python中chr、unichr、ord字符函数之间的对比
2016/06/16 Python
python 采集中文乱码问题的完美解决方法
2016/09/27 Python
Python sql注入 过滤字符串的非法字符实例
2020/04/03 Python
python 用Matplotlib作图中有多个Y轴
2020/11/28 Python
CSS3 简单又实用的5个属性
2010/03/04 HTML / CSS
德国、奥地利和瑞士最大的旅行和度假门户网站:HolidayCheck
2019/11/14 全球购物
2014年勤工助学工作总结
2014/11/24 职场文书
罚站检讨书
2015/01/29 职场文书
集结号观后感
2015/06/08 职场文书
移除Selenium中window.navigator.webdriver值
2022/06/10 Python