前言:真正意义上的前后端分离,前端ssr服务器渲染页面,加载静态资源,数据还是储存在后台服务器中。
1.packjson配置:
“script”:{ "dev": "node server", "start": "npm run build && cross-env NODE_ENV=production node server", // start命令即创造生产环境 "export": "next export", "build": "next build" }
2.强制把异步操作同步:
(1) async function(){ await axios请求 }
在使用 async/await 的时候,可以使用 Promise.all 来 await 多个 async 函数
await Promise.all([anAsyncCall(), thisIsAlsoAsync(), oneMore()])
(2) co,yield
import co from 'co' co(function * () { // *代表是异步的 let result = yield Promise.resolve(1) console.log(result) // 1 }).catch(function (err) { console.log(err) })
3.react生命周期(^15.6.2):
componentWillMount()
在组件挂载之前调用一次。如果在这个函数里面调用setState,本次的render函数可以看到更新后的state,并且只渲染一次。
componentDidMount()
在组件挂载之后调用一次。这个时候,子主键也都挂载好了,可以在这里使用refs(dom)。 // ssr渲染此生命周期被取消掉,直接用:
static getInitialProps = async (props) => { const channelRes = await fetcher(', {}) const channelInfos = channelRes.data return { channelRes, channelInfos, } }
componentWillUnMount() { clearInterval(this.timer); }
组件被销毁时调用,如果有计时器记得把组件内的计时器clear掉
4.react规范:
map生成的元素需要key值,组件合理闭合,无需包裹其他元素要 />结束
jsx写法:<>内容html渲染,{ }花括号内容js渲染,return()圆括号写内容 (jsx内组件名要大写字母开头!!!)
react性能优化:
尽量减少无意义的render,可用PureComponent(浅比较)或者 react-addons-pure-render-mixin插件,
import React, { Component } from 'react'; import PureRenderMixin from 'react-addons-pure-render-mixin'; class App extends Component { constructor(props) { super(props); this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this); }
5.设置默认props(react) :
static getDefaultProps = async ()=> {
await axios 请求
return {your need props}
}
next.js中用getInitialProps获取初始化数据,服务器渲染,componentDidmount周期失效
注:此props只最外层组件可用,子组件请用react生命周期请求接口
6.监视HTTP请求,获得url参数:
运用next.js服务端框架渲染页面,server.js文件里:
const Koa = require('koa') const router = require('koa-router')() //运用koa服务端解析框架搭开发环境 const next = require('next') const dev = process.env.NODE_ENV !== 'production' const app = next({ dev }) // dev可决定next库的版本是开发环境还是生产环境 const MobileDetect = require('mobile-detect') //node里的方法,判断请求源的设备信息 app.prepare() // next.js方法 .then(() => { const server = new Koa() router.get('/somePage/:somePageId', async (ctx) => { const actualPage = '/somePage' const queryParams = { somePageId: ctx.params.somePageId } const md = new MobileDetect(ctx.req.headers['user-agent']) if (md.phone()) { ctx.redirect('https://baidu.com/play/' + ctx.params.somePageId) //重定向url } else { await app.render(ctx.req, ctx.res, actualPage, queryParams)//next.js框架方法,用于渲染页面 } server.listen(5677, (err) => { if (err) throw err console.log('> Ready on http://localhost:5677') }) // 启动服务器并监视端口号5677 server.use(router.routes()) })
next.js里的render()方法用来手动渲染页面,参数(req, res, '/a', query):ctx.request,ctx.response,页面路径,路径所带参数(传入一个对象)
<div dangerouslySetInnerHTML={{ __html:item.mdata.videos[0].intro.slice(0, 300) + '...' }}></div>
注:dangerouslySetInnerHTML和_html成套搭配
vue:
<div v-html=""></div>
8.es6语法:
模版字符串:`${props.height}px` === ' '+props.height+'px'
处理数组:map(遍历并返回新数组),fliter(过滤并返回新数组),forEach(遍历改变不返回新数组),reduce(累计并返回结果)
箭头函数 :const a =(a,b)=> a+b === function a(a,b){return a+b}
对变量的声明 const:变量被声明后就不被改变,let:变量上下文块级作用域,声明一次即可
参数赋默认值:var test =(params = {} )=> { console.log(typeof params) } ; test(); //object (赋值为了防止忘了传参数报错)
{ a } === { a : a }
9.开发流程:
开发dev :package.json=>next.config.js=>server.js
生产start : next build => next.config.js=>server.js
10.数据请求:
前端用node服务器做页面渲染,数据储存还是在后台服务器里,
A服务器请求B服务器接口拿到数据,有两种方法:
1.cros后台设返回设置允许浏览器跨域。(跨域是浏览器这边的拦截)
2:Nginx转发
3:node的request模块做代理
下面介绍node怎么做转发:
const Koa = require('koa') const router = require('koa-router')() const request = require(‘request’) //做转发 const app = next() app.prepare() .then(() => { router.post('/api', function (req, res, next) { const objUrl = 'url§ionid=' + req.body.activityId request(objUrl, function (error, response, body) { if (!error && response.statusCode === '200') { res.send(body) } }) }) })