JSFiddle - React, Tailwind, and code Playground

by niuuin

HTML

<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="css/main.css">
  </head>

  <body>
    <main>
      <input type="number" name="index" hidden>
      <form id="user-form" novalidate>
        <input type="text" name="username" placeholder="用户名">
        <input type="email" name="email" placeholder="邮箱">
        <input type="number" name="balance" placeholder="余额">
        <button type="submit">提交</button>
      </form>

      <table id="user-table">
        <thead>
          <th>用户名</th>
          <th>邮箱</th>
          <th>余额</th>
          <th>操作</th>
        </thead>
        <tbody></tbody>
      </table>
    </main>


    <script src="js/main.js"></script>
  </body>

</html>

CSS

* {
  box-sizing: border-box;
}

:root {
  font-family: sans-serif;
  font-size: 14px;
}

input,
button {
  border: 1px solid #999;
  padding: .4rem;
  font-size: inherit;
  margin-bottom: .5rem;
  outline: none;
}

input {
  margin-top: .4rem;
}

form input,
form button {
  width: 100%;
}

.fill,
.delete {
  background: #eee;
  border: 1px solid rgb(214, 214, 214);
  color: #666;
  border-radius: 4px;
  font-size: .9rem;
}

.fill:hover,
.delete:hover {
  background: rgb(216, 216, 216);
  transition: all .3s;
}

button {
  background: #333;
  color: #fff;
}

main {
  padding: .5rem;
  margin: 0 auto;
  margin-top: 5rem;
  max-width: 40rem;
}

.error-container {
  background: pink;
  color: #c10;
  padding: .4rem;
  margin-bottom: .4rem;
  font-size: .8rem;
}

input.error {
  border: 1px solid #c10;
}

table {
  width: 100%;
  text-align: left;
  border-collapse: collapse;
}

td,
th {
  padding: .6rem;
  border-bottom: 1px solid rgba(0, 0, 0, .2);
}

th {
  border-color: rgba(0, 0, 0, .8);
}

[hidden] {
  display: none;
}

.text-right {
  text-align: right;
}

JavaScript

;
(function() {
  'use strict';

  let users = [{
      username: 'whh',
      email: '[email protected]',
      balance: '192',
    },
    {
      username: 'lsd',
      email: '[email protected]',
      balance: '123',
    },
    {
      username: 'zks',
      email: '[email protected]',
      balance: '134',
    },
  ];

  let elForm = document.getElementById('user-form');
  let elTable = document.getElementById('user-table');
  let elTbody = elTable.querySelector('tbody');
  let inputs = elForm.querySelectorAll('[name]');
  // 用于判断点击 更新 时,被更新数据的索引值 
  let elIndex = document.querySelector('[name=index]');

  boot();

  function boot() {
    // renderBody();
    bindSubmit();
  }

  /**
   * 绑定提交事件
   */
  function bindSubmit() {
    elForm.addEventListener('submit', e => {
      // 取消默认提交事件
      e.preventDefault();
      // 储存每一行的数据
      let row = {};
      // 循环所有输入组件
      inputs.forEach(it => {
        // 保存到 row
        row[it.name] = it.value;
      });

      // 如果记录索引组建中有值
      // 如 <input type="number" name="index" value="1">
      if (elIndex.value) {
        // 就更新数据
        users[elIndex.value] = row;
      } else {
        // 否则把新的数据推到 users 数组中
        users.push(row);
      }

      // 每次提交后清空 记录索引值的组件
      elIndex.value = '';

      // 每次提交后清空 form 中的数据
      elForm.reset();

      // 但数据发生改变,就重新渲染 table
      renderTbale();
    });
  }


  function renderTbale() {
    // 清空前一次渲染
    elTbody.innerHTML = '';
    // 循环 users - 用户数据
    // it 代表每一条用户数据,i 代表每条数据的索引值
    users.forEach((it, i) => {
      // 如果用户不存在就跳过
      // 因为删除用户时会将数据设为null
      if (!it)
        return;

      // 初始化组装字符串
      let html = '';
      // 创建表格行
      let tr = document.createElement('tr');
      tr.innerHTML = '';

      // 循环每一条用户数据
      // 如 {username: 'whh', ...'}
      // 此时 key 为 'username'
      // it[key] 为 'whh'
      // html += <td>whh</td>
      for (let key in it) {
        html += `<td>${it[key]}</td>`;
      };
      // 创建 操作部分的 按钮
      html += `<td...