美文网首页Next.js
八、Next.js,样式组件

八、Next.js,样式组件

作者: 小纠结在简书 | 来源:发表于2017-08-15 12:10 被阅读150次

    Next.js是一个新的通用JavaScript框架,它为基于React和服务器的Web应用提供了一个新的可选方案。

    Next.js目前已经开源,https://zeit.co/blog/next

    直到现在,样式化组件在很大程度上是事后才考虑的。但是你的应用程序应该有一些风格。

    对于一个反应应用,我们可以使用许多不同的技术来对它进行样式化,这些技术可以被分为两大类:

    1. 传统的基于css文件的样式(包括SASS,PostCSS等)
    2. CSS in Js styling

    因此,对于传统的基于css文件的样式(特别是使用SSR),有许多实际问题需要考虑,因此我们建议在为next.js设计样式时避免使用这种方法。

    相反,我们建议在JS中使用CSS,您可以使用它来对单个组件进行样式化,而不是导入CSS文件。

    Next.js在js框架中预装了CSS,称为styled-jsx,特别设计使你的生活更简单。它允许你以CSS 相似的规则缩写在组件中;除了组件(甚至是子组件),规则都不会对其他任何东西产生影响。

    这意味着,您的CSS规则是有作用域的。

    让我们看看如何使用styled-jsx。

    安装

    为了学习这个课程,你需要一个简单的Next.js应用程序,你可以下载下面的示例应用程序:

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

    你可以执行以下命令:

    npm install
    npm run dev
    

    现在,您可以通过导航到http://localhost:3000来访问该应用程序。

    样式化主页

    现在让我们在主页中添加一些样式。(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规则的地方。

    在您替换了这段代码之后,我们的博客主页将会是这样的:

    Paste_Image.png

    在上面的代码中,我们没有直接在样式标记中编写样式;相反,它是在一个模板字符串中编写的。

    现在尝试直接编写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>
    

    会发生什么呢?

    样式应该进入模板字符串中

    Styled jsx 是一个babel 插件。它将解析所有CSS并将其应用到构建过程中。(我们的样式在没有任何开销的情况下被应用)

    它还支持在styled-jsx中有约束。将来,您将能够在styled-jsx中使用任何动态变量。这就是CSS需要进入模板字符串的原因。({``})

    样式化和嵌套组件

    现在让我们添加一个简单的改变我们的主页。我们隔离链接组件如下:

    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 中替换上述内容

    会发生什么呢?

    对嵌套组件没有影响

    这就是你所看到的:

    Paste_Image.png

    如您所见,CSS规则对子组件内的元素没有影响。

    styled-jsx的这个特性可以帮助你管理更大的应用程序的样式。

    在这种情况下,您需要直接对子组件进行样式化。在我们的特殊情况下,我们需要为我们的链接组件做这个

    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>
    )
    

    另外,您可以使用全局选择器。

    全局样式

    有时,我们确实需要改变子组件内部的样式。在使用markdown和React时尤其如此。你可以在我们的帖子页面上看到。(pages/post.js)

    这就是全局样式的便捷之处。现在尝试使用styled-jsx添加一些全局样式规则。将下面的内容应用到pages/post.js。

    在应用以下内容之前,请在应用程序中安装以下组件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>
    )
    

    会发生什么呢?

    全局样式起作用

    是的,效果很好。它起作用了,因为我们的风格在全局范围内应用。

    虽然这个特性非常方便,但我们总是建议尝试编写范围内的样式(没有全局支持)。

    尽管如此,这仍然是一个比普通样式标签更棒的解决方案。使用styled-jsx,所有必要的前缀和CSS验证都是在一个babel插件中完成的,因此没有额外的运行时开销。

    下一步会怎么样

    我们刚刚在这里用styled-jsx挠了表面,还有很多你可以做的事情。更多信息请参考 styled-jsx GitHub

    下面还有许多其他的样式解决方案。这些都很好,所以也要看一看。other styling solutions

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

    相关文章

      网友评论

        本文标题:八、Next.js,样式组件

        本文链接:https://www.haomeiwen.com/subject/capmrxtx.html