最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 【笔记系列】Next.js 学习笔记

    正文概述 掘金(swanf)   2020-12-23   542

    Next.js 学习笔记

    ref: Create a Next.js App

    Code splitting 代码拆分

    能够自动进行代码拆分,仅在需要加载时加载对应的页面的代码。即首页加载时,其他页面还没初始化呢。

    即使页面总量很大,也能保证首页的快速加载。这意味着页面之间是独立的,因此某些报错的页面不会影响正常页面的渲染。

    prefetching 预加载

    在生产环境构建 production build 的 Next.js,只要包含有 Link 组件出现在视口时,Next.js 会在后台自动预先加载(prefetch)该页面中的内容。当用户点击时,目标页面已经加载完成了,因此页面能瞬间打开。

    总结

    Next.js 能够自动地优化应用,使用了诸如 代码拆分(Code splitting)、客户端路由(Client-side navigation)以及预加载(prefetching,在生产环境中)。

    关于 Link

    • Link 只是一个语义化空壳,里面还是要加上一个 <a> 把内容包起来的。
    • Link 只适用于组件间的路由转换,如果是外部链接,直接用 <a> 即可。
    • Link 上不能够加上属性(如 className、style 等),要加就直接加在里面的 <a> 标签上。

    关于 CSS/SASS

    • Next.js 自带对 SASS 的支持,直接 import 就可以用了。
    • 在 JSX 中直接写入 CSS:styled-jsx,能够让我们直接在 js 文件中的 React 组件中写 CSS,样式的将会是 scoped 的,即不会影响到别的组件。
    • Next.js 中自带对 styled-jsx 的支持,能够直接使用。此外也能够使用其他 CSS-in-JS 的库,如:styled-components 或者 emotion
    <style jsx>{`
      main {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
      }
    `}</style>
    

    关于静态资源

    静态资源(如图片、robots.txt、谷歌网站验证文件)都被放在了 top-level 目录 /public 里了。在 pages 的 js 页面中引用 public 目录中的资源可以直接像在根目录中引用一样。

    <img src="/vercel.svg"  className="logo" />
    

    元数据

    由于 JSX 本质上还是 JS,所以在处理元数据时需要不能直接用 createElement 方法(即 JSX)生成。因此需要引入元数据 React 组件。

    next/head 引入的 <Head> 是一个 Next.js 的 React 组件,用来构建页面的头部。里面能够定义页面的 <title> 了。

    Layout 组件

    • 接收一个 { 对象 } 作为参数,返回一个包起这个对象的 React 组件。类似于 Wrapper 的一个东西。实际上作用就是一个负责布局、添加样式的东西。
    • 在使用时只需要将该 Layout 引入,然后再把这个 Layout 包起想要添加布局的组件即可。

    CSS Module (.module.css)

    实际上就是一个 CSS 文件,只不过后缀从 .css 变成了 .module.css

    • 使用的时候把 .module.css 文件直接当作一个模块引入到 js 文件中,并把它赋给一个叫 styles 的样式对象。
    • 这个 styles 实际上就是一个样式模块,在 JSX 中使用的时候,直接在属性那里写 className = { styles.<在样式模块中对应的样式类名> }。但是实际上并不需要我们给类起名,CSS Module 会自动给该 JSX 组件生成一个独一无二的类名,并应用上我们指定的 样式模块 中的样式。
    • 它的目的是让我们能够为每个页面加载最少的 CSS 文件,从而缩小 包 bundle 的大小。
    • Next.js 会在构建时自动提取 JS 包里的 CSS Modules ,并且自动生成对应的 .css 文件。

    全局样式 (_app.js)

    • 全局样式放在了 pages/_app.js 中,我们在里面定义一个返回值是一个 <Component> (Component 为对应输入的组件对象)的函数 App,它将会是一个 top-level 的组件,在不同的组件中都会使用到它,即使在不同页面中跳转,我们也可以用它来保存 state。
    • 全局样式 global CSS 位于 top-level 的 styles/global.css,在 pages/_app.js 中 import 该样式文件即可生效(修改了 _app.js 必须 restart 应用)。
    • 因为修改全局样式会影响所有的元素,因此在 pages/_app.js 之外不能够引入 global.css
    export default function App({ Component, pageProps }) {
      return <Component {...pageProps} />;
    }
    

    classnames 用于增删 class

    classnames 是一个简单的库,能够让我们增删 class。 用法:

    import styles from "./alert.module.css";
    import cn from "classnames";
    
    export default function Alert({ children, type }) {
      return (
        <div
          className={cn({
            [styles.success]: type === "success",
            [styles.error]: type === "error",
          })}
        >
          {children}
        </div>
      );
    }
    

    alert.module.css

    .success {
      color: green;
    }
    .error {
      color: red;
    }
    

    PostCSS

    默认 Next.js 使用了 PostCSS 进行 CSS 的编译。需要配置 PostCSS 可以在 top-level 新建一个 postcss.config.js,这对使用如 Tailwind CSS 很有用。

    安装:

    npm install tailwindcss postcss-preset-env postcss-flexbugs-fixes
    

    配置 postcss.config.js:

    module.exports = {
      plugins: [
        "tailwindcss",
        "postcss-flexbugs-fixes",
        [
          "postcss-preset-env",
          {
            autoprefixer: {
              flexbox: "no-2009",
            },
            stage: 3,
            features: {
              "custom-properties": false,
            },
          },
        ],
      ],
    };
    

    配置 tailwind.config.js:

    // tailwind.config.js
    module.exports = {
      purge: [
        // Use *.tsx if using TypeScript
        "./pages/**/*.js",
        "./components/**/*.js",
      ],
      // ...
    };
    

    使用了 tailwind.js 可以,移除没用到的 css 文件。

    使用 Sass

    因为默认就配置好了,直接引入 Sass 都是可以的, 包括 .sass 和 .scss 两种拓展名的文件都能直接引入。可以使用组件级的 Sass,即以 .module.scss.module.sass 结尾的。

    事前需要先安装好 sass: npm install sass

    预渲染 Pre-rendering

    Next.js 最重要的概念之一,默认会对每个页面都进行预渲染(Pre-rendering)。

    • 这个在服务端进行的,即 SSR(Server-Side Rendering)。
    • Next.js 会提前对每个页面生成一份 HTML 代码,而不是在客户端拿到 raw HTML 让浏览器去解析、渲染整个页面。
    • 预渲染能够:提高性能 + 优化 SEO
    • 每个生成的 HTML 页面都只包含必须的 JS 代码。当页面被加载完成后,其 JS 代码才会开始运行并使得页面完全可交互的,这个过程叫做 水合(Hydration)。

    禁用 JS

    如果我们 disable javascript(F12,ctrl+shift+p, "disable javasctipt"),将会看到页面可以在没有 JS 的情况下渲染。这是因为 Next.js 进行了预渲染得出的 HTML。

    如果对一个纯粹的 React 页面(没使用 Next.js),我们将什么也看不见(因为 React 本质就是 JS 写 HTML,没 JS 写不了的)。

    两种预渲染

    1. 静态生成 Static Generation:仅在构建时生成 HTML,以后每次请求都复用这个生成的预渲染 HTML。
    2. 服务端渲染 SSR:对每次请求都用预渲染方法生成一个 HTML。

    Next.js 能够让我们自己选择每个页面是通过哪种预渲染方式。我们能创建混合 App,即对大部分页面使用 静态生成,对小部分页面使用 服务器渲染。

    什么时候使用

    推荐用 静态生成 Static Generation,因为可以只构建一次,然后放在 CDN 上去让用户访问,能够比 SSR 每次都通过服务器响应请求并进行一次预渲染更快。

    静态生成 Static Generation 适用于一切能够在用户请求之前就把页面整好的情况,如:

    • 电商
    • 博客
    • 主页
    • 帮助、文档

    如果页面内容和每次请求都相关,显示更新数据等,应该考虑 SSR,每次都让服务器预渲染一次,虽然慢些,但能使页面保持最新。

    使用 getStaticProps 来静态生成

    每当我们 export 一个组件时,我们可以同时 export 一个 async 的函数getStaticProps

    • 它能够在生产环境下(production)构建项目时运行,函数内我们可以进行一些外部数据获取,并把外部数据自动返回给页面组件作为参数。
    • 在开发环境下(development),该函数在组件遇到每一个请求时都会运行一遍。
    • 如果需要在每次请求时都运行一次数据获取,应该使用 服务器端渲染 SSR
    • getStaticProps 只能够在一个页面 page 中存在并 export 出去(如 pages/index.js),因为 React 有个限制,就是它需要等到把所有数据都加载完了才能够渲染这个页面。
    export default function Home(props) { ... }
    
    export async function getStaticProps() {
      // Get external data from the file system, API, DB, etc.
      const data = ...
    
      // The value of the `props` key will be
      //  passed to the `Home` component
      return {
        props: ...
      }
    }
    

    getStaticProps 获取的数据来源多种多样

    • 从 file system 读取
    • fetch 获取外部资源(Next.js 自带实现,不用 import 了)
    • 从后端数据库获取(因为 getStaticProps 仅在服务器端运行,因此不用担心它被发送到浏览器执行)

    使用 getServerSideProps 来 SSR

    当我们需要每次请求都进行一次数据请求(fetch),我们应该使用的就是 SSR,这时请求数据的方法不是 getStaticProps 而是 getServerSideProps 了。

    export async function getServerSideProps(context) {
      return {
        props: {
          // props for your component
        },
      };
    }
    

    相对于 getStaticPropsgetServerSideProps 方法多了一个 context 参数,它包含了当前请求的特定参数。

    通常情况下,如果不是获取的数据和请求息息相关的,不建议使用 getServerSideProps。它的首个比特时间(TTFB,Time to first byte)会比 getStaticProps 更慢,是因为每次它都需要服务器进行计算预渲染的结果,并且它在没配置的情况下是不能够被 CDN 缓存的。

    数据的客户端渲染 CSR

    注意不是页面的客户端渲染。

    • 将页面不需要动态数据的部分 静态生成(预渲染)
    • 当页面加载时,使用 JS 获取外部数据并补充页面剩余的部分
    • 可用于用户 dashboard 页,私人的页面、不需要 SEO、不需要预渲染、经常需要更新

    SWR 钩子

    如果时在客户端获取数据,使用 Next.js 制作的 swr 钩子能够很好地实现数据 fetch。它能够缓存、重新认证、焦点捕捉、定间隔重新获取等。

    全称 stale-while-revalidate,详见官方文档

    import useSWR from "swr";
    
    function Profile() {
      const { data, error } = useSWR("/api/user", fetch);
    
      if (error) return <div>failed to load</div>;
      if (!data) return <div>loading...</div>;
      return <div>hello {data.name}!</div>;
    }
    

    动态路由

    可创建静态路由如 pages/posts/[id].js,所有用左右中括号括起来的在 Next.js 中都是动态路由。

    使用 getStaticPaths 来获取所有可能的博客路径,使用 getStaticProps 来获取一个给定 id 的特定文章。

    动态路由匹配多个路径 catch-all routes

    pages/posts/[...id].js 能匹配 /posts/a/posts/a/b/posts/a/b/c 等等。

    getStaticPaths 中的 id 就需要返回一个数组了,因为这种多层级的路由是以数组形式设定的。

    return [
      {
        params: {
          // 能够生成 /posts/a/b/c
          id: ["a", "b", "c"],
        },
      },
    ];
    

    fallback

    getStaticPaths 的返回值有一个参数 fallback: false,意思是当你遇到 getAllPaths 的路径列表之外的页面的时候的处理是怎么样的。

    1. fallback: false 即所有不在 getStaticPaths 返回值里的路径都会返回 404 Page
    2. fallback: true, 那么 getStaticProps 的行为就会被改变了:1)所有的 getAllPaths 的路径列表里的页面会在构建时渲染成 HTML 2)所有路径列表之外的路径不会导致 404 Page,而是在对此路径的第一个请求时提供页面的“后备”(fallback)版本 3)后台,Next.js 将静态生成请求的路径,后续请求都会对应该生成的后备页面。
    3. fallback: blocking,即新的路径会被 SSR 且使用了 getStaticProps 里面的参数,这个结果会被缓存,因此该路径只会被请求一次。

    路由

    直接使用 Next.js 路由,应该 import 一个 useRouter


    起源地下载网 » 【笔记系列】Next.js 学习笔记

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元