站点图标 久久日记本

React引入样式

目录

*1.上节回顾

*2.分离样式

*3.添加loader与打包

*4.简单的引用Bootstrap样式

*5.另一种方式,将Bootstrap打包进代码

1.上节回顾

本篇文档发布在距离上篇大约半年之后,团队更换,所以间歇有些空闲来继续学习React。

在上一章react中简单的数据绑定与事件中,我们直接在jsx代码中的html写上了样式,这并不友好,于是我们必须分离样式成单独的文件了。

demo地址

panel.jsx文件

var React = require("react");

module.exports = React.createClass({
    displayName: 'panel',
    getInitialState:function () {
        return {
            logo: "http://img.99diary.com/blog/src/201603161422/logo.jpg",
            title: "让《疯狂动物城》背后的迪士尼告诉...",
            publishdate:"2016-03-15"
        }
    },
    render: function () {
        return <div style={{"width":"350px","height":"300px","border":"1px solid silver","MozBoxShadow":"2px 2px 13px #333333","WebkitBoxShadow":"2px 2px 13px #333333","BoxShadow":"2px 2px 13px #333333"}}>
                <div style= {{"width":"320px","height":"240px","margin":"auto auto","cursor":"pointer"}} onClick={this.showdetail}>
                    <img src={this.state.logo} width="320" height="240" />
                </div>
                <div style={{"width":"320px","height":"50px","margin":"10px auto auto auto"}}>
                    <div style={{"width":"40px","float":"left"}}>
                        <img src={this.state.logo} width="38" height="38" />
                    </div>

                    <div style={{"width":"280px","float":"left"}}>
                        <div>{this.state.title}</div>
                        <div>
                            {this.state.publishdate}
                        </div>
                    </div>
                </div>
            </div>
    },
    showdetail: function (event) {
        this.setState(
            {
                title: "《疯狂动物城2》即将上映",
                publishdate: "2016-03-16"
            }
        );
    }

});

样式和HTML,js 混杂,难以维护。

2.分离样式

我们新建项目,命名: import css

我们实现如图的简单效果:

分解:

文件夹结构如下:

project--
|
|--components
|       |
|       |--box.jsx
|       |--icon.jsx
|       |--index.jsx
|       |--info.jsx
|
|--css
|   |--box.css
|    
|--index.html
|--package.json
|--webpack.config.js

这种写法类似上一节。

小图标 icon.jsx

'use strict'
var React = require('react');
module.exports = React.createClass({
  displayName: 'Icon',
  render: function () {
    return (
      <div className='icon'>
        <div className='logo'>
        </div>
      </div>
    );
  }
}); 

图标右侧信息 info.jsx

'use strict'
var React = require('react');
module.exports = React.createClass({
  displayName: 'Info',
  render: function () {
    return (
      <div className='info'>
        <div className='title'>Customer Support</div>
        <div className='describe'>Lorem ipsum dolor sit amet, consectetur adip.</div>
      </div>
    );
  }
});

合并两者,取名 box.jsx

'use strict'
var React = require('react');
var Info = require('./info');
var Icon = require('./icon');
module.exports = React.createClass({
  displayName: 'Box',
  render: function () {
    return (
      <div className='box'>
        <Icon></Icon>
        <Info></Info>
      </div>
    );
  }
}); 

合并到 index.jsx

'use strict'
var ReactDOM = require('react-dom');
var Box = require('./box');

ReactDOM.render(
  <div>
    <Box></Box>
  </div>,
  document.getElementById('content')); 

分离出来的样式 box.css

.box{
  width: 320px;
  height: 60px;
  background-color: #52AD81;
  font-family: 'Open Sans',serif;
}
.box .icon{
  width: 60px;
  height: 60px;
  vertical-align: middle;
  float: left;
}
.box .icon .logo{
  width: 40px;
  height: 40px;
  background-color: white;
  margin: 10px auto 10px auto;
  border-radius: 20px;
  background-image: url('../image/0.png');
  /*background-image: url('http://localhost:8889/image/0.png')*/
  background-size: 100%;
  background-repeat: no-repeat;
}
.box .info{
  width: 260px;
  height: 60px;
  float: right;
  color: white;
}
.box .info .title{
  font-weight: 300;
  padding-left: 10px;
}
.box .info .describe{
  padding-left: 10px;
}
3.添加loader与打包

开始我在index.jsx中引入box.css

 require('react')

然而并什么卵用,查看了一些资料,原来是需要css loader,然后打包进去即可。

var webpack = require('webpack');
module.exports = {
  // entry: './components/index.jsx',
  entry: {
    index: ['./components/index.jsx', './css/box.css'] //将css文件打包进去
  },
  output: {
    filename: 'bundle.js',
    publicPath: 'http://localhost:8889/dist/'
  },
  module: {
    loaders: [
      {
        test: /\.jsx$/,
        loader: 'jsx-loader?insertPragma=React.DOM&harmony'
      },
      // 添加css loader
      {
        test: /\.css$/,
        loader: 'style-loader!css-loader'
      },
      // {
      //   test: /\.(png|jpg|gif)$/,
      //   loader: 'url-loader?limit=8192'
      // }, // <=8k的图片使用base64内联, 其他的继续用图片
      {
        test: /\.(png|jpg|gif)$/,
        loader: 'file-loader'
      } // 图片独立(兼容<IE8的browser)

    ]
  },
  externals: {
    react: 'React'
  },
  plugins: [
  ],
  resolve: {
    extensions: ['', '.js', '.jsx']
  }
}

CMD运行 > npm start

已经有上图中效果了。

4.简单的引用Bootstrap样式

直接引入bootstrap样式,我们可以在index.html添加引用,这里调用一个bootstrap的cdn链接:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>Hello World</title>
    <meta charset="utf-8" />
    <title>import css</title>
    <script src="./node_modules/react/dist/react-with-addons.js"></script>

    <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css"> 
    <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap-theme.min.css"> 
    <script src="http://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script> 
    <script src="http://cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</head>
<body>
    <div id="content">

    </div>

    <!--<script src="http://localhost:8889/vendor.js"></script>-->

    <!--注意这里的路径,要和配置文件端口设置一致-->
    <script src="http://localhost:8889/webpack-dev-server.js"></script>
    <script type="text/javascript" src="http://localhost:8889/dist/bundle.js"></script>

</body>
</html>

为了证明引用成功,我们添加一个div来展示bottstrap中panel效果

components文件夹中添加 panel.jsx 文件:

'use strict'
var React = require('react');
module.exports = React.createClass({
  displayName: 'Panel',
  render: function () {
    return (
      <div className='row'>
        <div className='col-sm-4'>
          <div className="panel panel-default">
            <div className="panel-heading">
              <h3 className="panel-title">Panel title</h3>
            </div>
            <div className="panel-body">
              Panel content
            </div>
          </div>
        </div>
      </div>
    );
  }
});

index.jsx中添加对panel的引用。

页面被刷新,bootstarp效果生效。

右侧可以猜测,我们自己分离的box.css也可以使用这种方式引用,这样就不会打包进我们的代码。

当然,这里是学习,我们可以尝试将bootstrap文件简单的打包到我们的代码中。

5.另一种方式,将Bootstrap打包进代码

删除html中关于Bootstrap的引用(注释会在打包时候报错...),将Bootstrap文件保存到本地并放入lib/bootstrap文件夹中,修改webpack.config.js

注意:bootstrap中引用了一些字体,需要去掉bootstrap.min.css中的字体引用,不然会报错

var webpack = require('webpack');
module.exports = {
  // entry: './components/index.jsx',
  entry: {
    index: [
      './components/index.jsx',
      './lib/bootstrap/bootstrap-theme.min.css',
      './lib/bootstrap/bootstrap.min.css',
      './lib/bootstrap/jquery.js',
      './lib/bootstrap/bootstrap.min.js',
      './css/box.css'
    ] //将css文件打包进去
  },
  output: {
    filename: 'bundle.js',
    publicPath: 'http://localhost:8889/dist/'
  },
  module: {
    loaders: [
      {
        test: /\.jsx$/,
        loader: 'jsx-loader?insertPragma=React.DOM&harmony'
      },
      // 添加css loader
      {
        test: /\.css$/,
        loader: 'style-loader!css-loader'
      },
      // {
      //   test: /\.(png|jpg|gif)$/,
      //   loader: 'url-loader?limit=8192'
      // }, // <=8k的图片使用base64内联, 其他的继续用图片
      {
        test: /\.(png|jpg|gif)$/,
        loader: 'file-loader'
      }// 图片独立(兼容<IE8的browser)
    ]
  },
  externals: {
    'react': 'React'
  },
  plugins: [

  ],
  resolve: {
    extensions: ['', '.js', '.jsx', 'css']
  }
}

CMD运行 > npm start

然而报错

bundle.js:21322 Uncaught Error: Bootstrap's JavaScript requires jQuery(…)

bootstrap库虽然被打包但是依然报错缺少jquery依赖。

尝试将jquery暴露给全局的变量的方法,修改webpack.config.js,

这里采用知乎网友给出的方法:

jQuery 直接在 html 中引入,然后在 webpack 中把它配置为全局即可。

externals: {
  jquery: 'window.$'
},

使用则直接 require 进来,反正 webpack 也不会把它打包进来。

var $ = require('jquery');

既然 $ 已经被设置为全局了,那么挂载在它下面的一系列 jQuery 插件就好办了,直接在 html 中引入。

<script type="text/javascript" src="./src/lib/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="./src/lib/jquery.nail.min.js"></script>

js 中引入 jquery 直接使用即可。

var $ = require('jquery');
$('#leftNav').nail();

然后看我们自己的代码,

修改webpack.config.js

  externals: {
    'react': 'React',
    'jquery': 'window.$'
  },

index.html中添加对jquery.js的引用:

<script src="lib/bootstrap/jquery.min.js"></script>

这个时候Juqey已经被暴露给全局,再次将bootstrap打包进去必然可以使用。

再次修改webpack.config.js:

  entry: {
    index: [
      './components/index.jsx',
      './lib/bootstrap/bootstrap-theme.min.css',
      './lib/bootstrap/bootstrap.min.css',
      './lib/bootstrap/bootstrap.min.js',
      './css/box.css'
    ] //将css文件打包进去
  },

CMD运行 > npm start,页面已经能够复现 4 所显示的效果。

本节源码地址(importcss)

上两节目录:

  1. 第一次使用webpack来写react
    源码地址(helloworld)

  2. react中简单的数据绑定与事件
    源码地址(panels)

退出移动版