八、Next.js,樣式組件

Next.js是一個新的通用JavaScript框架,它為基于React和服務(wù)器的Web應(yīng)用提供了一個新的可選方案。

Next.js目前已經(jīng)開源,https://zeit.co/blog/next

直到現(xiàn)在,樣式化組件在很大程度上是事后才考慮的。但是你的應(yīng)用程序應(yīng)該有一些風(fēng)格。

對于一個反應(yīng)應(yīng)用,我們可以使用許多不同的技術(shù)來對它進(jìn)行樣式化,這些技術(shù)可以被分為兩大類:

  1. 傳統(tǒng)的基于css文件的樣式(包括SASS,PostCSS等)
  2. CSS in Js styling

因此,對于傳統(tǒng)的基于css文件的樣式(特別是使用SSR),有許多實際問題需要考慮,因此我們建議在為next.js設(shè)計樣式時避免使用這種方法。

相反,我們建議在JS中使用CSS,您可以使用它來對單個組件進(jìn)行樣式化,而不是導(dǎo)入CSS文件。

Next.js在js框架中預(yù)裝了CSS,稱為styled-jsx,特別設(shè)計使你的生活更簡單。它允許你以CSS 相似的規(guī)則縮寫在組件中;除了組件(甚至是子組件),規(guī)則都不會對其他任何東西產(chǎn)生影響。

這意味著,您的CSS規(guī)則是有作用域的。

讓我們看看如何使用styled-jsx。

安裝

為了學(xué)習(xí)這個課程,你需要一個簡單的Next.js應(yīng)用程序,你可以下載下面的示例應(yīng)用程序:

git clone https://github.com/arunoda/learnnextjs-demo.git
cd learnnextjs-demo
git checkout clean-urls-ssr

你可以執(zhí)行以下命令:

npm install
npm run dev

現(xiàn)在,您可以通過導(dǎo)航到http://localhost:3000來訪問該應(yīng)用程序。

樣式化主頁

現(xiàn)在讓我們在主頁中添加一些樣式。(pages/index.js)

簡單的替換 pages/index.js 代碼如下:

import Layout from '../components/MyLayout.js'
import Link from 'next/link'

function getPosts () {
  return [
    { id: 'hello-nextjs', title: 'Hello Next.js'},
    { id: 'learn-nextjs', title: 'Learn Next.js is awesome'},
    { id: 'deploy-nextjs', title: 'Deploy apps with ZEIT'},
  ]
}

export default () => (
  <Layout>
    <h1>My Blog</h1>
    <ul>
      {getPosts().map((post) => (
        <li key={post.id}>
          <Link as={`/p/${post.id}`} href={`/post?title=${post.title}`}>
            <a>{post.title}</a>
          </Link>
        </li>
      ))}
    </ul>
    <style jsx>{`
      h1, a {
        font-family: "Arial";
      }

      ul {
        padding: 0;
      }

      li {
        list-style: none;
        margin: 5px 0;
      }

      a {
        text-decoration: none;
        color: blue;
      }

      a:hover {
        opacity: 0.6;
      }
    `}</style>
  </Layout>
)

看一下元素 <style jsx> 的作用。這就是我們編寫CSS規(guī)則的地方。

在您替換了這段代碼之后,我們的博客主頁將會是這樣的:

Paste_Image.png

在上面的代碼中,我們沒有直接在樣式標(biāo)記中編寫樣式;相反,它是在一個模板字符串中編寫的。

現(xiàn)在嘗試直接編寫CSS,而不需要模板字符串({``})。像這樣的:

<style jsx>
  h1, a {
    font-family: "Arial";
  }

  ul {
    padding: 0;
  }

  li {
    list-style: none;
    margin: 5px 0;
  }

  a {
    text-decoration: none;
    color: blue;
  }

  a:hover {
    opacity: 0.6;
  }
</style>

會發(fā)生什么呢?

樣式應(yīng)該進(jìn)入模板字符串中

Styled jsx 是一個babel 插件。它將解析所有CSS并將其應(yīng)用到構(gòu)建過程中。(我們的樣式在沒有任何開銷的情況下被應(yīng)用)

它還支持在styled-jsx中有約束。將來,您將能夠在styled-jsx中使用任何動態(tài)變量。這就是CSS需要進(jìn)入模板字符串的原因。({``})

樣式化和嵌套組件

現(xiàn)在讓我們添加一個簡單的改變我們的主頁。我們隔離鏈接組件如下:

import Layout from '../components/MyLayout.js'
import Link from 'next/link'

function getPosts () {
  return [
    { id: 'hello-nextjs', title: 'Hello Next.js'},
    { id: 'learn-nextjs', title: 'Learn Next.js is awesome'},
    { id: 'deploy-nextjs', title: 'Deploy apps with ZEIT'},
  ]
}

const PostLink = ({ post }) => (
  <li>
    <Link as={`/p/${post.id}`} href={`/post?title=${post.title}`}>
      <a>{post.title}</a>
    </Link>
  </li>
)

export default () => (
  <Layout>
    <h1>My Blog</h1>
    <ul>
      {getPosts().map((post) => (
        <PostLink key={post.id} post={post}/>
      ))}
    </ul>
    <style jsx>{`
      h1, a {
        font-family: "Arial";
      }

      ul {
        padding: 0;
      }

      li {
        list-style: none;
        margin: 5px 0;
      }

      a {
        text-decoration: none;
        color: blue;
      }

      a:hover {
        opacity: 0.6;
      }
    `}</style>
  </Layout>
)

在 pages/index.js 中替換上述內(nèi)容

會發(fā)生什么呢?

對嵌套組件沒有影響

這就是你所看到的:

Paste_Image.png

如您所見,CSS規(guī)則對子組件內(nèi)的元素沒有影響。

styled-jsx的這個特性可以幫助你管理更大的應(yīng)用程序的樣式。

在這種情況下,您需要直接對子組件進(jìn)行樣式化。在我們的特殊情況下,我們需要為我們的鏈接組件做這個

const PostLink = ({ post }) => (
  <li>
    <Link as={`/p/${post.id}`} href={`/post?title=${post.title}`}>
      <a>{post.title}</a>
    </Link>
    <style jsx>{`
      li {
        list-style: none;
        margin: 5px 0;
      }

      a {
        text-decoration: none;
        color: blue;
        font-family: "Arial";
      }

      a:hover {
        opacity: 0.6;
      }
    `}</style>
  </li>
)

另外,您可以使用全局選擇器。

全局樣式

有時,我們確實需要改變子組件內(nèi)部的樣式。在使用markdown和React時尤其如此。你可以在我們的帖子頁面上看到。(pages/post.js)

這就是全局樣式的便捷之處?,F(xiàn)在嘗試使用styled-jsx添加一些全局樣式規(guī)則。將下面的內(nèi)容應(yīng)用到pages/post.js。

在應(yīng)用以下內(nèi)容之前,請在應(yīng)用程序中安裝以下組件react-markdown :npm install --save react-markdown

import Layout from '../components/MyLayout.js'
import Markdown from 'react-markdown'

export default (props) => (
  <Layout>
   <h1>{props.url.query.title}</h1>
   <div className="markdown">
     <Markdown source={`
This is our blog post.
Yes. We can have a [link](/link).
And we can have a title as well.

### This is a title

And here's the content.
     `}/>
   </div>
   <style jsx global>{`
     .markdown {
       font-family: 'Arial';
     }

     .markdown a {
       text-decoration: none;
       color: blue;
     }

     .markdown a:hover {
       opacity: 0.6;
     }

     .markdown h3 {
       margin: 0;
       padding: 0;
       text-transform: uppercase;
     }
  `}</style>
  </Layout>
)

會發(fā)生什么呢?

全局樣式起作用

是的,效果很好。它起作用了,因為我們的風(fēng)格在全局范圍內(nèi)應(yīng)用。

雖然這個特性非常方便,但我們總是建議嘗試編寫范圍內(nèi)的樣式(沒有全局支持)。

盡管如此,這仍然是一個比普通樣式標(biāo)簽更棒的解決方案。使用styled-jsx,所有必要的前綴和CSS驗證都是在一個babel插件中完成的,因此沒有額外的運行時開銷。

下一步會怎么樣

我們剛剛在這里用styled-jsx撓了表面,還有很多你可以做的事情。更多信息請參考 styled-jsx GitHub

下面還有許多其他的樣式解決方案。這些都很好,所以也要看一看。other styling solutions

本文翻譯自:https://learnnextjs.com/basics/styling-components

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容