React - 4 案例

购物车

  • index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import store from './store/index'
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>
);

  • app.js
import React from 'react';
import Add from './add';
import List from "./list"
import Footer from "./footer"
function App() {
  return (
    <div className="App">
          <h1>购物车</h1>
      <Add />
      <List />
      <Footer></Footer>
    </div>
  );
}

export default App;
  • add.js
import React,{useState} from "react";
import { useDispatch } from "react-redux";

function Add () {
    let [name, setName] = useState("")
    let [price, setPrice] = useState("")
    let dispatch =useDispatch()
    return (
        <div>
            添加商品:
            <input
                type="text"
                placeholder="请输入商品名称"
                value={name}
                onChange={({ target }) => {//注意{target}
                    setName(target.value)
                }}
            ></input>
            <input 
                type="text" 
                placeholder="请输入商品价格"
                value = {price}
                onChange={({target})=>{
                    setPrice(parseFloat(target.value));
                }}
            />
            <button
                onClick={() => {
                    dispatch({
                        type: 'add',
                        data: {
                            id: Date.now(),
                            name,
                            price,
                            number: 1
                        }
                    });
                    setName('')
                    setPrice('')
             }}
            >添加商品</button>
        </div>
    )
}
export default Add
  • store
    • index.js
import { createStore } from 'redux'
import reducer from './reducer'
export default createStore(reducer)
  • reducer.js
export default function reducer(state=[
    {
        id: 0,
        name: "苹果",
        price: 7,
        number: 1
    },{
        id: 1,
        name: "栗子",
        price: 16,
        number: 2
    }
],action){
    // eslint-disable-next-line default-case
    switch(action.type){
        case "add":
            state.push(action.data);
            return [...state];
        case "plus":
            for(let i = 0; i<state.length; i++){
                    if(state[i].id === action.id){
                        ++state[i].number;
                        return [...state];
                    }
            }
        // eslint-disable-next-line no-fallthrough
        case "minus":
            for(let i = 0; i<state.length; i++){
                if(state[i].id === action.id){
                    (state[i].number>0)&&(--state[i].number);
                    return [...state];
                }
        }    
    }
    return state;
}
  • list.js
import React from "react";
import { useSelector } from "react-redux";
import Li from './Li'
function List () {
    let data=useSelector(state=>state)
    return (
        <ul>
            {data.map(item => (<Li key={item.id} data={item}></Li>))}
        </ul>
    )
}
export default List
  • Li,js
import React from "react";
import {useDispatch} from "react-redux";
function Li (props) {
    let { id, name, price, number } = props.data
    let dispatch = useDispatch();
    return (
        <li>
            {name}-{price}元/件-共<button
                onClick={() => {
                    dispatch({
                        type: "minus",
                        id
                    })
                }}
            >-</button>{number}件<button
            onClick={() => {
                dispatch({
                    type: "plus",
                    id
                })
            }}
            >+</button>-共{price * number}元
        </li>
    )
}
export default Li
  • footer.js
import React from "react";
import { useSelector } from "react-redux";
function Footer () {//首字母一定要大写
    let data = useSelector(state=>(state.filter(item=>item.number>0)));
    let number = data.reduce((n1, n2)=> {
        return n1+n2.number
    },0)
    let allPrice=data.reduce((n1, n2)=> {
        return n1+n2.number*n2.price
    }, 0)
    let maxPrice=data.reduce((n1, n2)=> {
        return Math.max(n1,n2.price)
    },0)
    return (
        <footer>总计:{number}件商品;共计花费{allPrice}元,最贵单价为{maxPrice}元</footer>
    )
}
export default Footer

CSS Modules

  • 在 create-react-app 中的使用:
    • .css .sass 正常文件
    • [name].module.css [name].module.sass 需要模块化的文件,文件命名加上module
import React from 'react';
import "./reset.css";
import styleed from "./app.module.css";///引入
import Child from './child';
function App() {
  return (
    <div className={styleed.app}>//使用,会自动生成hash后缀,避免命名重复
      <Child />
      <div className="box"></div>
    </div>
  );
}

export default App;

  • CSS Modules 使用
    • 局部 声明:local(.className) .className 使用 styled.className
    • 全局 :global(.className)
body {
    margin: 0;
}
.app {
    margin: 0 auto;
    width: 800px;
    min-height: 100px;
    border: 1px solid #000;
}

:global(.box) {
    width: 300px;
    height: 300px;
    border: 2px solid #000;
    border-radius: 50%;
}
import React, { Fragment } from 'react';
import style from "./child.module.css";
/**
 * 
 *  box 全局通用
 */
function Child() {
  return (
     <Fragment>
         <h1 id={style.title}>标题</h1>
         <div className={style.app}>
            <div></div>
        </div>
        <div className="box"></div>
        <div className={style.app2}></div>
     </Fragment> 
   
  );
}

export default Child;

Ant Design

官网: https://ant.design/index-cn

  • 使用
  • 最基本使用
    • 安装 npm install antd
    • 引入 import { DatePicker } from ‘antd’; ReactDOM.render(, mountNode); import
      ‘antd/dist/antd.css’;
  • 在 create-react-app 中使用 antd 并模块化我们的样式
    • npm i antd
    • npm i react-app-rewired customize-cra react-app-rewired 自定义 create-react-app 的配置
    • 修改 package.json
    • “scripts”: {
      “start”: “react-scripts start”,
      “start”: “react-app-rewired start”,
      “build”: “react-scripts build”,
      “build”: “react-app-rewired build”,
      “test”: “react-scripts test”,
      “test”: “react-app-rewired test”, }
    • 安装 babel-plugin-import npm i babel-plugin-import babel-plugin-import 是一个用于按需加
      载组件代码和样式的 babel 插件
    • 在项目根目录创建一个 config-overrides.js 用于添加babel-plugin-import配置

用到什么组件,就打包什么组件的样式,不用全部样式引入

  • 在项目中使用 less 语法
    • 安装 npm i less less-loader
    • 修改 config-overrides.js 配置
const { override, fixBabelImports, addLessLoader } = require('customize-cra');

module.exports = override(
    fixBabelImports('import', {
        libraryName: 'antd',
        libraryDirectory: 'es',
        style: true,///引入less之后修改
    }),
    addLessLoader({///引入less之后修改
        javascriptEnabled: true,
        modifyVars: { '@primary-color': '#1DA57A' },
    }),
);
import React from 'react';
import {Button} from "antd";
import "./index.less";
function App() {
  return (
    <div className="wrap">
        <Button>这是一个按钮</Button>
    </div>
  );
}

export default App;
@w:100px;
.wrap {
    width: @w;
    height: @w;
    background: #ccc;
}

搭建 CNode 案例

测试接口地址:https://cnodejs.org/api

在这里插入图片描述

antd样式导入配置

create-react-app 脚手架搭建的react项目不支持 less,配置less步骤:

方式1 使用 react-app-rewired 和 customize-cra 来自定义 create-react-app 的 webpack 配置。

步骤 ,见上个案例,遇到问题:

  • npm i react-app-rewired安装不上,导致npm satrt启动不成功,转为使用yarn add react-app-rewired
方式2 使用 craco (一个对 create-react-app 进行自定义配置的社区解决方案)
  • 1.现在我们安装 craco 并修改 package.json 里的 scripts 属性。
$ yarn add @craco/craco
/* package.json */
"scripts": {
-   "start": "react-scripts start",
-   "build": "react-scripts build",
-   "test": "react-scripts test",
+   "start": "craco start",
+   "build": "craco build",
+   "test": "craco test",
}
  • 2.按照 配置主题 的要求,自定义主题需要用到类似 less-loader 提供的 less 变量覆盖功能。我们可以引入 craco-less 来帮助加载 less 样式和修改变量。
    首先把 src/App.css 文件修改为 src/App.less,然后修改样式引用为 less 文件。
/* src/App.js */
- import './App.css';
+ import './App.less';
/* src/App.less */
- @import '~antd/dist/antd.css';
+ @import '~antd/dist/antd.less';
  • 3.然后安装 craco-less
$ yarn add craco-less
  • 4.修改 craco.config.js 文件如下。注意官网示例没有配置webpack的src路径,所以@import ‘~antd/dist/antd.less’;报错
在这里插入代码片
const CracoLessPlugin = require('craco-less');
const path = require("path");
module.exports = {
    babel: {
        plugins: [
            [
                "import",
                {
                    "libraryName": "antd",
                    "libraryDirectory": "es",
                    "style": true// true 针对less
                }
            ]
        ]
    },
    plugins: [
        {
            plugin: CracoLessPlugin,
            options: {
                lessLoaderOptions: {
                    lessOptions: {
                        modifyVars: { '@primary-color': '#1DA57A' }, //主题色
                        javascriptEnabled: true,
                    },
                },
            },
        },
    ],
    //配置src路径
    webpack: {
        alias: {
            "@": path.resolve("src"),
        },
    },
};
方式3 :使用 create-react-app 提供的 yarn run eject 命令将所有内建的配置暴露出来

参考文献:react+antd 项目使用.less以及引入babel-plugin-import实现按需加载

  • 1、使用命令将配置文件暴露出来
yarn eject  // 或者 npm run eject
  • 2、安装 less,less-loader 插件
yarn add less less-loader
  • 3.打开webpack.config.js文件
  • 4.添加配置代码
    添加less的部分
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const lessRegex = /\.less$/;
const lessModuleRegex = /\.module\.less$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;
   //less
            {
              test: lessRegex,
              exclude: lessModuleRegex,
              use: getStyleLoaders(
                {
                  importLoaders: 2,
                  sourceMap: isEnvProduction
                    ? shouldUseSourceMap
                    : isEnvDevelopment,
                },
                'less-loader'
              ),
              sideEffects: true,
            },
            {
              test: lessModuleRegex,
              use: getStyleLoaders(
                {
                  importLoaders: 2,
                  sourceMap: isEnvProduction
                    ? shouldUseSourceMap
                    : isEnvDevelopment,
                  modules: {
                    getLocalIdent: getCSSModuleLocalIdent,
                  },
                },
                'less-loader'
              ),
            },

遇到的问题

  • antd组件的使用,最新版本和旧版本有所不同
  • require
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值