javascript 练习 写一个简单 另类录入 电脑组装报价表 可打印

数据格式

(1代表cpu、2代表主板、3代表内存、。。。)

1@i3 12100 @630

2@H610 @480

3@DDR4 3200 16G @220

4@500G M.2 @299

5@300W电源 @150

6@小机箱 @85

7@GT 730G 4G @350

8@WD 2T @399

9@飞利浦 24Led @580

主代码 Html + JS

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>电脑组装报价表</title>
  <link rel="stylesheet" href="./iconfont/iconfont.css">
  <link rel="stylesheet" href="css/index.css" />
</head>

<body>
  <h1>电脑组装报价表</h1>
    <form class="info no-print" autocomplete="off">
         <textarea placeholder="请输入内容" class="uname" name="uname" lay-verify="required" style="width: 500px;height: 100px;"></textarea>

          <button class="add">
            <i class="iconfont icon-tianjia"></i>录入
          </button>

    </form>
  
  

  <div class="title no-print">共有数据<span>0</span>条</div>
  <table>
    <thead>
      <tr>
        <th>ID</th>
        <th>类别</th>
        <th>配件名称</th>
        <th>数量</th>
        <th>单价</th>
        <th>金额</th>
        <th>录入时间</th>
        <th>操作</th>
      </tr>
    </thead>
    <tbody>
      <!-- 表格内容 -->
    </tbody>
  </table>
  <div class="title heji">大写: <strong>零</strong>&nbsp;&nbsp;&nbsp;    合计:<span>0</span>元</div>
  <div class="boot">
    <button class="printer no-print">
      <i class="iconfont icon-tianjia"></i>打印
    </button>
  </div>
  
  <script src="js/daxie.js"></script>
  <script>
    // 参考数据
    const initData = [
      {
        stuId: 1,
        bname: 'cpu',
        goods: 'i3 12100',
        sl: 1,
        dj: 630,
        je: 630,
        time: '2099/9/9 08:08:08'
      }
    ]
    // 1. 渲染业务
    // 1.1 先读取本地存储的数据
    // (1). 本地存储有数据则记得转换为对象然后存储到变量里面,后期用于渲染页面
    // (2). 如果没有数据,则用 空数组来代替
    let count = 0 //合计数据
    
    const arr = JSON.parse(localStorage.getItem('data')) || []
    console.log('数据arr:',arr)
    // 1.2 利用map和join方法来渲染页面
    const tbody = document.querySelector('tbody')
    function render() {
      // (1). 利用map遍历数组,返回对应tr的数组
      const trArr = arr.map(function (ele, index) {
        count +=parseInt(ele.dj)
        return `
          <tr>
            <td>${ele.stuId}</td>
            <td>${ele.bname}</td>
            <td>${ele.goods}</td>
            <td>${ele.sl}</td>
            <td>${ele.dj}</td>
            <td>${ele.je}</td>
            <td>${ele.time}</td>
            <td>
              <a href="javascript:" data-id="${index}">
                <i class="iconfont icon-shanchu"></i>
                删除
              </a>
            </td>
          </tr>
        `
        count +=ele.dj // 合计储存数据
      })

      console.log(trArr)
      // (2). 把数组转换为字符串 join
      // (3). 把生成的字符串追加给tbody 
      tbody.innerHTML = trArr.join('')
      // 显示共计有几条数据
      document.querySelector('.title span').innerHTML = arr.length
    }
    render()

    // 2. 新增业务
    const info = document.querySelector('.info')
    const uname = document.querySelector('.uname')
    


    // 2.1 form表单注册提交事件,阻止默认行为
    info.addEventListener('submit', function (e) {
      e.preventDefault()
      // 2.2 非空判断
      if (!uname.value) {
        return alert('输入内容不能为空')
      }
      const dataT = [] // 接收新的数据对像
      
      let lines = uname.value.split("\n");
      console.log(lines)
      // console.log(typeof(lines))
      // 2.3 给 arr 数组追加对象,里面存储 表单获取过来的数据
      for (let line of lines) {
                    let parts = line.split("@"); // 将每行分割成组件编号、名称和价格
                    console.log(parts)
                    let [number, name, price] = parts;
                    price = price.trim(); // 去除价格两侧的空格

                    // 根据组件编号创建对象,并添加到结果数组中
                    if (number === "1") {
                        dataT.push({ id: "1", lx: "cpu", pj: name, jg: price });
                    } else if (number === "2") {
                        dataT.push({ id: "2", lx: "主板", pj: name, jg: price });
                    } else if (number === "3") {
                        dataT.push({ id: "3", lx: "内存", pj: name, jg: price });
                    } else if (number === "4") {
                        dataT.push({ id: "4", lx: "固态硬盘", pj: name, jg: price });
                    } else if (number === "5") {
                        dataT.push({ id: "5", lx: "电源", pj: name, jg: price });
                    } else if (number === "6") {
                        dataT.push({ id: "6", lx: "机箱", pj: name, jg: price });
                    } else if (number === "7") {
                        dataT.push({ id: "7", lx: "外置显卡", pj: name, jg: price });
                    } else if (number === "8") {
                        dataT.push({ id: "8", lx: "机械硬盘", pj: name, jg: price });
                    } else if (number === "9") {
                        dataT.push({ id: "9", lx: "显示器", pj: name, jg: price });
                    }

                }

      for (let i = 0; i < dataT.length; i++){     
        arr.push({
        // 处理 stuId:数组最后一条数据的stuId + 1      
        stuId: arr.length ? arr[arr.length - 1].stuId + 1 : 1,
        bname: dataT[i].lx,
        goods: dataT[i].pj,
        sl: 1,
        dj: dataT[i].jg,
        je: dataT[i].jg,
        time: new Date().toLocaleString()
      })
      // 2.4 渲染页面和重置表单(reset()方法)
      render()
      }
      
      this.reset() // 重置表单

      // 2.5 把数组重新存入本地存储里面,记得转换为JSON字符串存储
      localStorage.setItem('data', JSON.stringify(arr))
      location.reload(); // 刷新显示储存数据 合计结果
    })

    // 3. 删除业务
    // 3.1 采用事件委托形式,给 tbody 注册点击事件
    tbody.addEventListener('click', function (e) {
      // 判断是否点击的是删除按钮  A 链接
      if (e.target.tagName === 'A') {
        // alert(11)
        // 3.2 得到当前点击链接的索引号。渲染数据的时候,动态给a链接添加自定义属性例如 data-id="0"
        console.log(e.target.dataset.id)

        // 确认框 确认是否要真的删除
        if (confirm('您确定要删除这条数据吗?')) {
          // 3.3 根据索引号,利用 splice 删除数组这条数据
          arr.splice(e.target.dataset.id, 1)
          // 3.4 重新渲染页面 
          render()
          // 3.5 把最新 arr 数组存入本地存储
          localStorage.setItem('data', JSON.stringify(arr))
          location.reload(); // 刷新显示储存数据 合计结果
        }
      }
    })
  
  // 显示小写合计
  console.log('数量:',count)
  document.querySelector('.heji span').innerHTML = count
   // 显示大写合计,用numberTochinese 函数转成大写
  let Num = numberToChinese(count)
  document.querySelector('.heji strong').innerHTML = Num
// 打印
  function printPage() {
    window.print();
  }
  // 监听打印按钮
  const pr = document.querySelector('.printer')
  pr.addEventListener('click',function(){
    printPage();
  })

  

  </script>
</body>

</html>

注1:其中数据转换:

let parts = line.split("@"); // 将每行分割成组件编号、名称和价格

// 根据组件编号创建对象,并添加到结果数组中

if (number === "1") {

dataT.push({ id: "1", lx: "cpu", pj: name, jg: price });

} else if (number === "2") {

dataT.push({ id: "2", lx: "主板", pj: name, jg: price });

} else if (number === "3") {

dataT.push({ id: "3", lx: "内存", pj: name, jg: price });

} else if (number === "4") {

dataT.push({ id: "4", lx: "固态硬盘", pj: name, jg: price });

} else if (number === "5") {

dataT.push({ id: "5", lx: "电源", pj: name, jg: price });

} else if (number === "6") {

dataT.push({ id: "6", lx: "机箱", pj: name, jg: price });

} else if (number === "7") {

dataT.push({ id: "7", lx: "外置显卡", pj: name, jg: price });

} else if (number === "8") {

dataT.push({ id: "8", lx: "机械硬盘", pj: name, jg: price });

} else if (number === "9") {

dataT.push({ id: "9", lx: "显示器", pj: name, jg: price });

}

注2:两条内存 未解决 可以当 双条 合成 1套

注3:打印 只是用CSS 隐藏 不打印的

CSS代码 index.css

css 复制代码
* {
  margin: 0;
  padding: 0;
}

a {
  text-decoration: none;
  color: #721c24;
}

h1 {
  text-align: center;
  color: #333;
  margin: 20px 0;

}

.title {
  width: 933px;
  height: 50px;
  line-height: 50px;
  padding-right: 15px;
  border: 1px solid #ebebeb;
  margin: 10px auto;
  background-color: #f2f2f2;
  text-align: right;
}

.title span {
  display: inline-block;
  vertical-align: middle;
  height: 20px;
  margin: -3px 5px 0;
  text-align: center;
  line-height: 20px;
  color: #f26934;
  font-weight: 700;
}

table {
  margin: 0 auto;
  width: 950px;
  border-collapse: collapse;
  color: #3c3637;
}

th {
  padding: 10px;
  background: #f2f2f2;
  font-size: 18px;
  text-align: left;
}

td,
th {
  border: 1px solid #bbbaba;
  padding: 15px;
}

td {

  color: #080808;
  font-size: 16px;

}

tbody tr {
  background: #fff;
}

tbody tr:hover {
  background: #fbfafa;
}

tbody a {
  display: inline-block;
  width: 80px;
  height: 30px;
  text-align: center;
  line-height: 30px;
  color: #fff;
  background-color: #f26934;
}

.info {
  width: 900px;
  margin: 50px auto;
  text-align: center;
}

.info input,
.info select {
  width: 100px;
  height: 30px;
  outline: none;
  border: 1px solid #ebebeb;
  padding-left: 5px;
  box-sizing: border-box;
  margin-right: 10px;
}

.info button {
  width: 70px;
  height: 30px;
  background-color: #5dbfd8;
  outline: none;
  border: 0;
  color: #fff;
  cursor: pointer;
  font-size: 14px;
}

.info button:hover {
  background-color: #52abc1;
}

.printer {
  width: 70px;
  height: 30px;
  background-color: #5dbfd8;
  outline: none;
  border: 0;
  color: #fff;
  cursor: pointer;
  font-size: 14px;
}

.printer:hover {
  background-color: #52abc1;
}

.boot {
  margin: 0 auto;
  width: 950px;
  padding-bottom: 20px;
  text-align: center;
}

/* 对打印机进行样式设置 */
@media print {
  .no-print {
    display: none; /* 在打印时隐藏带有no-print类的元素 */
  }
  td,th {
    border: 1px solid #1a1a1a;
    padding: 15px;
  }
}

@media print {
  @page {
    margin-top: 0;
    margin-bottom: 0;
  }
  header, footer {
    display: none;
  }
}

小写转大写 JS代码 daxie.js

javascript 复制代码
function numberToChinese(num) {
    const digit = {
      0: '零',
      1: '壹',
      2: '贰',
      3: '叁',
      4: '肆',
      5: '伍',
      6: '陆',
      7: '柒',
      8: '捌',
      9: '玖',
    };
    const unit = ['', '拾', '佰', '仟', '万', '亿'];
   
    const moneyStr = String(num.toFixed(2));
    const moneyArr = moneyStr.split('.');
    const integralPart = Number(moneyArr[0]);
    const decimalPart = Number(moneyArr[1]);
   
    const toChinese = (num) => {
      const numArr = String(num).split('');
      const len = numArr.length;
      const resultArr = [];
   
      for (let i = 0; i < len; i++) {
        const digitIndex = Number(numArr[i]);
        if (i !== len - 1 && digitIndex !== 0) {
          resultArr.push(digit[digitIndex], unit[len - i - 1]);
        } else {
          resultArr.push(digit[digitIndex]);
        }
      }
      return resultArr.join('');
    };
   
    if (num === 0) {
      return '零元整';
    }
   
    const result = toChinese(integralPart);
    if (decimalPart === 0) {
      return result + '元整';
    } else {
      return result + '元' + toChinese(decimalPart) + '角';
    }
  }
   
  console.log(numberToChinese(123456789.12)); // 壹亿贰仟叁佰肆拾伍万陆仟柒佰捌拾玖元壹角贰分
相关推荐
栈老师不回家5 分钟前
Vue 计算属性和监听器
前端·javascript·vue.js
芊寻(嵌入式)6 分钟前
C转C++学习笔记--基础知识摘录总结
开发语言·c++·笔记·学习
前端啊龙10 分钟前
用vue3封装丶高仿element-plus里面的日期联级选择器,日期选择器
前端·javascript·vue.js
一颗松鼠14 分钟前
JavaScript 闭包是什么?简单到看完就理解!
开发语言·前端·javascript·ecmascript
准橙考典34 分钟前
怎么能更好的通过驾考呢?
人工智能·笔记·自动驾驶·汽车·学习方法
小远yyds35 分钟前
前端Web用户 token 持久化
开发语言·前端·javascript·vue.js
阿伟来咯~1 小时前
记录学习react的一些内容
javascript·学习·react.js
吕彬-前端1 小时前
使用vite+react+ts+Ant Design开发后台管理项目(五)
前端·javascript·react.js
学前端的小朱2 小时前
Redux的简介及其在React中的应用
前端·javascript·react.js·redux·store
guai_guai_guai2 小时前
uniapp
前端·javascript·vue.js·uni-app