19

Next.js和Nuxt.js的语法比较,Vue和React的两大SSR解决方案

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzI0MDIwNTQ1Mg%3D%3D&%3Bmid=2676493168&%3Bidx=2&%3Bsn=74a33ac9cd42f900d1d85788f8a59d4d
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

7zaiAfB.png!web

React.js和Vue.js都是很好的框架,而 Next.js Nuxt.js 甚至将它们带入了一个新的高度,这有助于我们以更少的配置和更好的可维护性来创建应用程序。但是,如果你必须经常在框架之间切换,在深入探讨另一个框架之后,你可能会轻易忘记另一个框架中的语法。在本文中,我总结了这些框架的基本语法和方案,然后并排列出。我希望这可以帮助我们尽快掌握语法。

上一篇我们已经介绍了: React.js和Vue.js的语法并列比较

目录

  • Assets

    • Next.js

    • Nuxt.js

  • 基本路由

  • 动态路由

  • Link

  • Fetch-On-Server

    • Next.js

    • Nuxt.js

  • Layout

    • Next.js

    • Nuxt.js

  • 错误页面

    • Next.js

    • Nuxt.js

  • Meta-Tag

  • Context

    • Next.js

    • Nuxt.js

  • CLI

    • React.js: create-react-app

    • Next.js: create-next-app

    • Vue.js: vue-cli

Assets

Next.js

/*
|- public/
|-- my-image.png
*/
function MyImage() {
  return <img src="/my-image.png" alt="my image" />;
}

Nuxt.js

assets,默认情况下,Nuxt使用vue-loader、file-loader和url-loader来提供强大的assets服务。

<!--
|- assets/
  |- image.png
-->
<img src="~/assets/image.png" alt="image" />

static,自动服务

<!--
|- static/
  |- image.png
-->
<img src="/image.png" alt="image" />

基本路由

Next.js

|- pages/
  |- index.js        → href="/"
  |- blog/index.js   → href="/blog"

Nuxt.js

|- pages/
  |- index.vue       → href="/"
  |- blog/index.vue  → href="/blog"

动态路由

Next.js

|- pages/
  |- blog/[slug].js           → href="/blog/:slug" (eg. /blog/hello-world)
  |- [username]/[option].js   → href="/:username/:option" (eg. /foo/settings)
  |- post/[...all].js         → href="/post/*" (eg. /post/2020/id/title)

Nuxt.js

|- pages/
  |- blog/[slug].vue         → href="/blog/:slug" (eg. /blog/hello-world)
  |- _username/_option.vue   → href="/:username/:option" (eg. /foo/settings)

Link

Next.js

import Link from "next/link";
function Home() {
  return (
    <Link href="/">
      <a>Home</a>
    </Link>
  );
}

Nuxt.js

<template>
  <nuxt-link to="/">Home page</nuxt-link>
</template>

Fetch-On-Server

Next.js

getInitialProps只能在每个页面的默认导出中使用

< Next.js 9.3 (class component)

import fetch from "isomorphic-unfetch";
export default class Page extends React.Component {
  static async getInitialProps(ctx) {
    const res = await fetch(`https://.../data`);
    const data = await res.json();
    return { props: { data } };
  }
  render() {
    // Render data...
  }
}

< Next.js 9.3 (function component)

import fetch from "isomorphic-unfetch";
function Page({ data }) {
  // Render data...
}
Page.getInitialProps = async (ctx) => {
  const res = await fetch(`https://.../data`);
  const data = await res.json();
  return { props: { data } };
};

>= Next.js 9.3

import fetch from "isomorphic-unfetch";
function Page({ data }) {
  // Render data...
}
export async function getServerSideProps() {
  const res = await fetch(`https://.../data`);
  const data = await res.json();
  return { props: { data } };
}
export default Page;

Nuxt.js

<template>
  <div v-if="$fetchState.error">发生了一些错误 :sob:</div>
  <div v-if="$fetchState.pending">Loading...</div>
  <div v-else>
    <h1>{{ post.title }}</h1>
    <pre>{{ post.body }}</pre>
    <button @click="$fetch">刷新</button>
  </div>
</template>
<script>
  import fetch from "node-fetch";
  export default {
    data() {
      return {
        post: {},
      };
    },
    async fetch() {
      this.post = await this.$http.$get("xxx");
    },
    fetchOnServer: true,
  };
</script>

Layout

Next.js

./pages/_app.js :自动应用于所有页面

export default function MyApp({ Component, pageProps }) {
  return (
    <React.Fragment>
      <MyHeader />
      <Component {...pageProps} />
      <MyFooter />
    </React.Fragment>
  );
}

Nuxt.js

layouts/with-header-footer.vue :创建布局

<template>
  <div>
    <MyHeader />
    <nuxt />
    <MyFooter />
  </div>
</template>

pages/index.vue :应用布局

<template>
  <!-- 你的模板 -->
</template>
<script>
  export default {
    layout: "with-header-footer",
  };
</script>

错误页面

Next.js

pages/_error.js

function Error({ statusCode }) {
  return (
    <p>
      {statusCode
        ? `An error ${statusCode} occurred on server`
        : "An error occurred on client"}
    </p>
  );
}
Error.getInitialProps = ({ res, err }) => {
  const statusCode = res ? res.statusCode : err ? err.statusCode : 404;
  return { statusCode };
};
export default Error;

Nuxt.js

layouts/error.vue

<template>
  <div class="container">
    <h1 v-if="error.statusCode === 404">Page not found</h1>
    <h1 v-else>一个错误发生</h1>
    <nuxt-link to="/">Home page</nuxt-link>
  </div>
</template>
<script>
  export default {
    props: ["error"],
    layout: "blog", // 你可以为错误页面设置自定义布局
  };
</script>

Meta-Tag

Next.js

import Head from "next/head";
function IndexPage() {
  return (
    <div>
      <Head>
        <title>My page title</title>
        <meta name="viewport" content="initial-scale=1.0, width=device-width" />
      </Head>
      <p>Hello world!</p>
    </div>
  );
}

Nuxt.js

<template>
  <h1>{{ title }}</h1>
</template>
<script>
  export default {
    data() {
      return {
        title: "Hello World!",
      };
    },
    head() {
      return {
        title: this.title,
        meta: [
          // 为了避免在子组件中使用重复的元标记,可以使用hid键设置唯一的标识符
          {
            hid: "description",
            name: "description",
            content: "My custom description",
          },
        ],
      };
    },
  };
</script>

Context

Next.js

getInitialProps只能在每个页面的默认导出中使用

function Page({ data }) {
  // 渲染数据...
}
Page.getInitialProps = async (context) => {
  const { pathname, query, asPath, req, res, err } = context;
  // pathname - 当前路径,这是/pages中的页面路径。
  // query - 将URL的查询字符串部分作为对象进行解析
  // asPath - 浏览器中显示的实际路径(包括查询)的字符串
  // req - HTTP request object (server only)
  // res - HTTP response object (server only)
  // err - 如果在渲染过程中遇到任何错误,则为错误对象。
  return { props: { project: "next" } };
};

Nuxt.js

export default {
  asyncData(context) {
    // 通用keys
    const {
      app,
      store,
      route,
      params,
      query,
      env,
      isDev,
      isHMR,
      redirect,
      error,
    } = context;
    // 服务器端
    if (process.server) {
      const { req, res, beforeNuxtRender } = context;
    }
    // 客户端
    if (process.client) {
      const { from, nuxtState } = context;
    }
    return { project: "nuxt" };
  },
};

CLI

React.js: create-react-app

npx create-react-app react-template

Next.js: create-next-app

npx create-next-app next-template

Vue.js: vue-cli

yarn global add @vue/cli
vue create vue-template

推荐阅读

新手React开发人员容易做错的5件事

谷歌Chrome浏览器终于让你可以对标签进行整理和分组了

7个很棒的JavaScript产品步骤引导库

2020年排名前11位的静态网站生成器,有你用过的吗?

重磅下载!《2020前端工程师必读手册》,阿里巴巴前端委员会推荐!

让你在2020年成为前端大师的9个项目

感谢您的阅读和关注,看完三件事:

如果对你有帮助,帮忙文章右下角点个 在看 如果有什么问题欢迎 留言 交流,还可以 转发 ,这是对作者最大的帮助。 b6feIbe.png!web

IVbEZrz.png!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK