nextjs基础使用

默认的约定只有一个,那就是所有页面都放在 pages 下面,静态资源放在 public 下面

组件中获取router信息

import { useRouter } from 'next/router';

const Page = () => {
  const router = useRouter();

  return (
    <Layout>
      <h1>{router.query.title}</h1>
      <p>This is the blog post content.</p>
    </Layout>
  );
};

路由

动态路由: 创建文件 /pages/p/[id].js(不能用 /pages/p/post-[id].js
https://github.com/zeit/next.js/tree/canary/examples/dynamic-routing

// href后面接自己定义的路径,as接真实展示在浏览器上的URL
<Link href="/p/[id]" as={`/p/${props.id}`}>
  <a>{props.id}</a>
</Link>

路由跳转

import Link from 'next/link';
import Router from 'next/router';

<Link href="/">跳转</Link>
Router.push('/')

shallow routing: 改变路由的query值而不触发getInitialProps函数, 方法为router.push(url, null, {shallow: true})

function Page() {
  const router = useRouter()

  useEffect(() => {
    // Always do navigations after the first render
    router.push('/?counter=10', null, { shallow: true })
  }, [])

  useEffect(() => {
    // The counter changed!
  }, [router.query.counter])
}

请求后端

function parseURL(ctx, s) {
  if (ctx.req) {
    return `http://0.0.0.0:${port}${s}`;
  }
  return s;
}

Page.getInitialProps = async function (context) {
  const { id } = context.query;
  // 注意的是这里的URL不能直接用/api/index
  // 因为服务端渲染时必须要是完整的URL,例如http://0.0.0.0/api/index
  const res = await fetch(parseURL(`/api/index`));
  const show = await res.json();

  console.log(`Fetched show: ${show.name}`);

  return { show };
};

共用Layout

pages/_app.js

import Layout from "../components/layout/Layout";

export default function MyApp({ Component, pageProps }) {
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  );
}

css样式

styled-jsx: https://github.com/zeit/styled-jsx
css样式写在jsx里面, 而且这些css样式只对当前组件起作用,不会对父/子组件起作用

<style jsx>{`
    h1,
    a {
      font-family: 'Arial';
    }
`}</style>

全局作用域的css样式:在 pages/_app.js 中直接import

import '../styles.css'

// This default export is required in a new `pages/_app.js` file.
export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

组件级别的css:基于CSS Modules, 命名方式为 [name].module.css, 引入方式为import styles from 'your-css-file'

import styles from './Button.module.css'

export function Button() {
  return (
    <button
      type="button"
      // Note how the "error" class is accessed as a property on the imported
      // `styles` object.
      className={styles.error}
    >
      Destroy
    </button>
  )
}

使用less

https://github.com/zeit/next-plugins/tree/master/packages/next-less

$ cnpm i -S less @zeit/next-less

不使用css module

// next.config.js
const withLess = require('@zeit/next-less')
module.exports = withLess({
  /* config options here */
})
// 组件中使用
import './style.less';

使用css module

// next.config.js
const withLess = require('@zeit/next-less')
module.exports = withLess({
  cssModules: true,
  cssLoaderOptions: {
    importLoaders: 1,
    localIdentName: "[local]___[hash:base64:5]",
  }
})
// 组件中使用
import styles from './index.less';

内置API: pages/api

pages/api/user.js 对应路由 /api/user

export default (req, res) => {
  res.statusCode = 200
  res.setHeader('Content-Type', 'application/json')
  res.end(JSON.stringify({ name: 'John Doe' }))
}

配合koajs使用

https://github.com/zeit/next.js/tree/canary/examples/custom-server-koa

const Koa = require('koa');
const next = require('next');
const Router = require('koa-router');

const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();

app.prepare().then(() => {
  const server = new Koa();
  const router = new Router();

  router.get('/a', async ctx => {
    await app.render(ctx.req, ctx.res, '/a', ctx.query);
    ctx.respond = false;
  })

  router.all('*', async ctx => {
    await handle(ctx.req, ctx.res);
    ctx.respond = false;
  })

  server.use(async (ctx, next) => {
    ctx.res.statusCode = 200;
    await next();
  })

  server.use(router.routes());
  server.listen(port, () => {
    console.log(`> Ready on http://localhost:${port}`);
  });
});

preact

https://github.com/zeit/next.js/tree/canary/examples/using-preact

antd

https://github.com/zeit/next.js/blob/canary/examples/with-ant-design

$ npm init next-app --example with-ant-design app_name

部署

pm2部署

$ pm2 start npm --name "app_name" -- start

需要注意的坑

获取user-agent,要先判断是服务端还是客户端再获取

Page.getInitialProps = async ({ req }) => {
  const userAgent = req ? req.headers['user-agent'] : navigator.userAgent
  return { userAgent }
}

<Link href="/"></Link>中必须要包含<a></a>

原文地址:https://www.cnblogs.com/elimsc/p/14778916.html