yaofly2012 / note

Personal blog
https://github.com/yaofly2012/note/issues
44 stars 5 forks source link

styled-jsx #66

Open yaofly2012 opened 5 years ago

yaofly2012 commented 5 years ago

一、是什么

babel插件

1.1 Slogon

Full, scoped and component-friendly CSS support for JSX (rendered on the server or the client).

1. 功能齐全(full)

支持CSS全部的功能,没有阉割CSS。

2. 封装的(scoped)

保证了写CSS不会影响其他CSS

3. 组件友好的(component-friendly)

  • CSS直接跟组件写在一起,更方便coding。

    4. 支持服务端和客户端渲染

    还需研究

    1.2 功能列表

二、使用

2.1 封装

假如render方法返回值:

<div>
                <div className="wrapper">
                    <h1>wrapper 1</h1>
                </div>
                <div className="wrapper">
                    <h1>wrapper 2</h1>
                    <p>Done is Done</p>
                    <div>
                        <p>Do it</p>
                        <ul>
                            <li>Name</li>
                            <li>Age</li>
                        </ul>
                    </div>
                    <style jsx>{`
                        .wrapper {                            
                            border: 1px solid #ccc;
                        }
                        p {
                            color: blue;
                        }
                        h1 {
                            color: #FFF;
                        }
                        div {
                            background: red;
                        }
                        @media (max-width: 600px) {
                            div {
                            background: blue;
                            }
                        }
                    `}</style>
                </div>
            </div> 

则最终生成的HTML & CSS

<div>
    <div class="wrapper">
        <h1>wrapper 1</h1></div>
    <div class="jsx-1648893254 wrapper">
        <h1 class="jsx-1648893254">wrapper 2</h1>
        <p class="jsx-1648893254">Done is Done</p>
        <div class="jsx-1648893254">
            <p class="jsx-1648893254">Do it</p>
            <ul class="jsx-1648893254">
                <li class="jsx-1648893254">Name</li>
                <li class="jsx-1648893254">Age</li>
            </ul>
        </div>
    </div>
</div>

head元素里会被插入style样式:

.wrapper.jsx-4101443392{
    border:1px solid #ccc;
}
p.jsx-4101443392{
    color:blue;
}
h1.jsx-4101443392{
    color:#FFF;
}
div.jsx-4101443392{
    background:red;
}
@media (max-width:600px){
    div.jsx-4101443392{
        background:blue;
    }
}
  1. <style jsx>元素的父元素和父元素的子孙元素都添加了一个唯一的className; 为啥父元素也被添加唯一的className?待研究 看这样子灵感来自shadowdom。
  2. <style jsx>元素包裹的CSS的选择器都追加了一个唯一的className修饰。

通过这个唯一的className这样就实现了CSS的封装性(组件的CSS不会影响其他CSS)。

注意:

  1. <style jsx>元素的父元素的父元素,组件不会添加唯一的className。

  2. 组件可以包含多个<style jsx>元素,但多个<style jsx>元素必须是兄弟元素,不可以是父子关系,否则会报错:

    SyntaxError: Detected nested style tag: styled-jsx only allows style tags to be direct descendants (children) of the outermost JSX element i.e. the subtree root.

  3. 所以一般把 <style jsx>元素作为组件根元素的子元素。

  4. <style jsx>元素本质上组件的子组件,当组件卸载时,<style jsx>元素生成的CSS也是被删除的(由JSXStyle组件控制)。

  5. index.js:2178 Warning: Received true for a non-boolean attribute jsx. If you want to write it to the DOM, pass a string instead: jsx="true" or jsx={value.toString()}. in style (at phone.jsx:34) in Phone (at phone.jsx:84)

targeting-the-root 必有父组件,且不可以是React.Component组件,要不然不能不能识别是