前端小白学 React 框架(七)

49 阅读1分钟

购物车综合小案例

我正在参加「掘金·启航计划」

效果展示

用之前所学的知识做一个综合小案例,实现的效果如下:

屏幕录制2023-05-16 20.43.56.gif

代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>购物车综合小案例</title>
  <style>
    table {
      border-collapse: collapse;
      user-select: none;
    }

    th,td {
      padding: 10px 16px;
      border: 1px solid #aaa;
    }
  </style>
</head>
<body>
  <div id="root"></div>

  <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

  <script type="text/babel">
    // 1.定义App根组件
    class App extends React.Component {
      constructor() {
        super();

        this.state = {
          message: '购物车综合小案例',
          books: [
            { id: 1, name: '算法导论', date: '2006-9', price: 85, count: 0 },
            { id: 2, name: 'UNIX编程艺术', date: '2006-2', price: 59, count: 0 },
            { id: 3, name: '编程珠玑', date: '2008-10', price: 39, count: 0 },
            { id: 4, name: '代码大全', date: '2006-3', price: 128, count: 0 },
          ]
        }
      }

      change(type, id) {
        const { books } = this.state;
        const target = books.find(book => book.id === id);
        switch(type){
          case 'increment':
            target.count++;
            break;
          case 'decrement':
            target.count--;
            break;
          default:
            break;
        }
        this.setState({ books });
      }

      remove(id) {
        let { books } = this.state;
        books = books.filter(book => book.id !== id);
        this.setState({ books });
      }

      getBookList() {
        const { books } = this.state;

        return books.map(book => {
          const ID = book.id;
          return (
            <tr key={ID}>
              <td>{ID}</td>
              <td>{book.name}</td>
              <td>{book.date}</td>
              <td>{this.formatPrice(book.price)}</td>
              <td>
                <button disabled={book.count === 0} onClick={() => this.change('decrement', ID)}>-</button>
                {book.count}
                <button onClick={() => this.change('increment', ID)}>+</button>
              </td>
              <td>
                <button onClick={() => this.remove(ID)}>移除</button>
              </td>
            </tr>
          )
        })
      }

      formatPrice(price) {
        return ${price.toFixed(2)}`
      }

      getTotal() {
        return this.formatPrice(this.state.books.reduce((pre, curr) => 
          pre += curr.count * curr.price, 0));
      }

      render() {
        const { message } = this.state;
        return (
          <div>
            <h1>{message}</h1>
            <table>
              <thead>
                <tr>
                  <th>ID</th>
                  <th>书籍名称</th>
                  <th>出版日期</th>
                  <th>价格</th>
                  <th>购买数量</th>
                  <th>操作</th>
                </tr> 
              </thead>
              <tbody>
                {this.getBookList()}
              </tbody>
            </table>
            <div>总价: {this.getTotal()}</div>
          </div>
        )
      }
    }

    // 2.创建root并渲染App组件
    const root = ReactDOM.createRoot(document.querySelector('#root'));
    root.render(<App />);
  </script>
</body>
</html>

写在最后

如果大家喜欢的话可以收藏本专栏,之后会慢慢更新,然后大家觉得不错可以点个赞或收藏一下 🌟。

本节的源码放在作者的GitHub仓库里,分别是: