NEXT.JS中值得一提的功能
一边吃零食一边看完了Next.JS的文档,写的不是很复杂,demo尝试起来也很快速:grimacing:
我在看Next.JS文档的时候,是通过yarn init
手动搭建的空项目,然后按照文档一点一点写demo
如果您不喜欢init,可以尝试使用create-next-app
,接下来我们也提到一些关于create-next-app
的安装和使用
本篇文章主要是对Nextjs文档读后体会,以及发现的新鲜事物,事实上他包含了router等多种服务,后续也会写一下与其他单一组件的区别
NEXT.JS是什么?
粗略看了一下,大概是 就是 一种 react
的 SSR
同构框架。
看一下network,server端渲染还是还是很明显的,个人还是能够接受
等会,插一句,谁还不是个小仙男咋地
创建NEXT.JS 项目
首先安装create-next-app
npm install -g create-next-app
创建Create-next-app项目
create-next-app my-app
这里,官方给出了一些example,你可以直接创建这些Example
create-next-app --example basic-css my-app
create-next-app --example [example-name] [your-app-name]
NextJS总结
SSR 渲染
这是nextjs
的关键nextjs
是在 server
端 render React
的一个框架
那 React 不是前端框架么?所谓三大前端框架之一么 ( Angular,React 和 Vue )
这又在后端渲染 react
,到底图个啥呢?后端不是有 express
,或者 koa
,koa2
,eggjs
等各种框架么?
以前的多页面站点是在服务端渲染的,输出到浏览器时已经有了完整的骨架( html ),这样爬虫抓到时可以分析页面标题,内容等等,做 seo 容易,那时的技术栈是 jsp,php 等等。现在流行的前端框架在这方面是开了倒车,一个空的骨架,一个很大的 js,抓到浏览器以后才开始渲染完整的页面,爬虫就很为难了,因为它没法执行 js 啊,此外,白屏时间也是由于前端渲染带来的问题。于是又有了服务端渲染,让渲染这一步再回到服务端,在服务端模拟浏览器环境,给 react 和 vue 等框架一个可执行的上下文,就是为了提前得到完整的 html。是的,前端就是这么扯蛋。
r u kidding me? 我是混蛋?前端狗?
对样式的支持
- 支持style-jsx
当我看到官方给的这个demo的时候,摆弄新耳机的我还以为自己再看vue教程,刷新了一个React小萌新的世界观,原来React也可以这么写
export default () =>
<div>
Hello world
<p>scoped!</p>
<style jsx>{`
p {
color: blue;
}
div {
background: red;
}
@media (max-width: 600px) {
div {
background: blue;
}
}
`}</style>
<style global jsx>{`
body {
background: black;
}
`}</style>
</div>
- 使用 CSS / Sass / Less / Stylus files
支持用.css, .scss, .less or .styl,需要配置默认文件 ,讲道理没有css是世界上最痛苦的事情,不管有没有样式预处理器,css总得支持下吧,何况都支持
静态文件服务
在根目录下新建文件夹叫static
。代码可以通过/static/来引入相关的静态资源。
_注意:不要自定义静态文件夹的名字,只能叫static ,因为只有这个名字 Next.js 才会把它当作静态资源。
生成
这里可不是NextJS的提供的组件,而是一种特定的,可以自定义title,meta,这个我从未想过但是细想一下,似乎跟旧项目有些什么相同之处
获取数据以及组件生命周期
相信你注意到,当页面渲染时加载数据,我们使用了一个异步方法getInitialProps
。它能异步获取 JS 普通对象,并绑定在props
上
当服务渲染时,getInitialProps
将会把数据序列化,就像JSON.stringify
。所以确保getInitialProps
返回的是一个普通 JS 对象,而不是Date, Map 或 Set类型。
当页面初始化加载时,getInitialProps
只会加载在服务端。只有当路由跳转(Link组件跳转或 API 方法跳转)时,客户端才会执行getInitialProps
。
注意:getInitialProps
将不能使用在子组件中。只能使用在pages页面中。
只有服务端用到的模块放在getInitialProps
里,请确保正确的导入了它们,可参考import them properly
。 否则会拖慢你的应用速度。
你也可以给无状态组件定义getInitialProps:
const Page = ({ stars }) =>
<div>
Next stars: {stars}
</div>
Page.getInitialProps = async ({ req }) => {
const res = await fetch('https://api.github.com/repos/zeit/next.js')
const json = await res.json()
return { stars: json.stargazers_count }
}
export default Page
getInitialProps入参对象的属性如下:
pathname - URL 的 path 部分
query - URL 的 query 部分,并被解析成对象
asPath - 显示在浏览器中的实际路径(包含查询部分),为String类型
req - HTTP 请求对象 (只有服务器端有)
res - HTTP 返回对象 (只有服务器端有)
jsonPageRes - 获取数据响应对象 (只有客户端有)
err - 渲染过程中的任何错误
可以获取到URL信息,that's great!
nextjs中,生命周期大概是这样的getInitialProps => render =>componentDidMount...
多了一个getInitialProps
Router-Link
值得关注的内容
- 拦截器 popstate
import Router from 'next/router'
Router.beforePopState(({ url, as, options }) => {
// I only want to allow these two routes!
if (as !== "/" || as !== "/other") {
// Have SSR render bad routes as a 404.
window.location.href = as
return false
}
return true
});
- URL 对象用法
import Router from 'next/router'
const handler = () =>
Router.push({
pathname: '/about',
query: { name: 'Zeit' }
})
export default () =>
<div>
Click <span onClick={handler}>here</span> to read more
</div>
http://localhost:3000/about?name='Zeit'
- 路由事件
你可以监听路由相关事件。 下面是事件支持列表:
- routeChangeStart(url) - 路由开始切换时触发
- routeChangeComplete(url) - 完成路由切换时触发
- routeChangeError(err, url) - 路由切换报错时触发
- beforeHistoryChange(url) - 浏览器 history 模式开始切换时触发
- hashChangeStart(url) - 开始切换 hash 值但是没有切换页面路由时触发
- hashChangeComplete(url) - 完成切换 hash 值但是没有切换页面路由时触发
4.浅层路由
浅层路由允许你改变 URL 但是不执行getInitialProps生命周期。你可以加载相同页面的 URL,得到更新后的路由属性pathname和query,并不失去 state 状态。
你可以给Router.push 或 Router.replace方法加shallow: true参数。
动态导入
你可以动态导入 JavaScript 模块(如 React 组件)。
动态导入相当于把代码分成各个块管理。Next.js 服务端动态导入功能,你可以做很多炫酷事情。
下面介绍一些动态导入方式:
- 基础支持 (同样支持 SSR)
import dynamic from 'next/dynamic'
const DynamicComponent = dynamic(import('../components/hello'))
export default () =>
<div>
<Header />
<DynamicComponent />
<p>HOME PAGE is here!</p>
</div>
- 自定义加载组件
import dynamic from 'next/dynamic'
const DynamicComponentWithCustomLoading = dynamic(
import('../components/hello2'),
{
loading: () => <p>...</p>
}
)
export default () =>
<div>
<Header />
<DynamicComponentWithCustomLoading />
<p>HOME PAGE is here!</p>
</div>
- 禁止使用 SSR
import dynamic from 'next/dynamic'
const DynamicComponentWithNoSSR = dynamic(import('../components/hello3'), {
ssr: false
})
export default () =>
<div>
<Header />
<DynamicComponentWithNoSSR />
<p>HOME PAGE is here!</p>
</div>
- 同时加载多个模块
import dynamic from 'next/dynamic'
const HelloBundle = dynamic({
modules: () => {
const components = {
Hello1: import('../components/hello1'),
Hello2: import('../components/hello2')
}
return components
},
render: (props, { Hello1, Hello2 }) =>
<div>
<h1>
{props.title}
</h1>
<Hello1 />
<Hello2 />
</div>
})
export default () => <HelloBundle title="Dynamic Bundle" />
这个像 create-react-app
?
是或不是.
是,因为它让你的 SSR 开发更简单。
不是,因为它规定了一定的目录结构,使我们能做以下更高级的事:
服务端渲染
自动代码分割
此外,Next.js 还提供两个内置特性:
路由与懒加载组件: (通过引入 next/link)
修改的组件: (通过引入 next/head)
如果你想写共用组件,可以嵌入 Next.js 应用和 React 应用中,推荐使用create-react-app。你可以更改import保持代码清晰。
怎么解决 CSS 嵌入 JS 问题?
Next.js 自带styled-jsx库支持 CSS 嵌入 JS。而且你可以选择其他你喜欢的嵌入方法到你的项目中,可参考文档嵌入样式。
为什么使用新路由?
Next.js 的特别之处如下所示:
路由不需要被提前知道
路由总是被懒加载
顶层组件可以定义生命周期getInitialProps来阻止路由加载(当服务端渲染或路由懒加载时)
因此,它由下面两部分组成:
每个顶层组件都将会收到一个url对象,来检查 url 或修改历史记录
组件用于包装如(<a/>)标签的元素容器,来执行客户端转换。
我们使用了些有趣的场景来测试路由的灵活性,例如,可查看nextgram。
怎么获取数据?
getInitialProps是一个异步函数async(也就是函数将会返回个Promise)。你可以在任意位置获取数据。
就这么简单?这些东西我都用过!
大佬,请留下您的联系方式,我们床上聊
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
评论已关闭