Vue 组件编写:简易计算器

话不多说,码上开始。


建立项目

  1. 首先下载 安装 Node.js 环境,它会自动安装 npm 包管理工具。在使用之前我们修改一下 npm 包的下载路径,不然放在 C 盘怎么得了?在命令行中输入 npm config ls 可以看到 prefix 的值就是下载路径,输入 npm config set prefix "你的路径" 就可以修改。
  2. 安装 vue-cli 脚手架工具npm install -g vue-cli,参数 -g 表示全局安装(路径在之前设置的 prefix 中),否则就是本地安装(路径在当前目录)。
  3. 建立项目,在某目录下,输入 vue init webpack-simple 项目名称,参数 webpack-simple 是一个项目模板;按提示输入相关信息后,将自动新建项目文件夹,输入 cd 文件夹名称 进入目录,输入 npm install,在当前项目路径下载所需的包;输入 npm run dev 就可运行了。 dev 是 package.json里面定义的脚本命令,作用是启动服务器。

打开 Vue.app 文件,我们就可以在里面愉快的写组件了。
这里不再介绍 Vue 的基本知识,若要学习请移步 Vue2.x 教程


需求分析

其实文章开头说的 话不多说,码上开始 是一种十分错误的做法。我就是在想当然之后——按照脑海中最初浮现的逻辑——马上开始写界面,吭哧吭哧地开始写事件处理程序。随后,在测试中痛苦地发现,功能太简陋,简单的单次计算并不能满足我们印象中对于计算器的期待。

好吧,推倒重来,如果上天再给我一次机会,我会好好地做需求分析……

首先,我们打开一个计算器看看它有什么功能:
1124590-20170709121014759-475160985.png

也就是说,计算器应该支持单次运算、连续计算、继续计算,遵循运算符的优先级顺序,并具有一定的容错机制。

几经修改,最后整理流程图如下:
1124590-20170709121034134-738082299.png


组件结构

  • 首先,为了进行四则运算,我们需要一个操作符栈 oprStack 和一个数值栈 numStack
  • 为了显示算式的功能,我们需要一个数组 cacheArr 顺序记录输入和操作符和数值。
  • 由于显示部分应该绑定一个字符串变量 cacheStr,此变量又于上述数组相关,那么为了保持数据结构的简单,对于这个字符串变量,我们使用计算属性。
  • 一些缓存变量,inputData preType
  • 一些标志变量,calculated inputShow errorOccurred

那么自然而然地,计算器组件的结构设计如下:

<template>
  <div id="calculator">
    ...
    <div id="panel">
      <hr>
      <div>{{ cacheStr }}</div>
      <hr>
      <div :class="{'text-danger' : errorOccurred}">{{ inputData }}</div>
      <hr>
    </div>
    <div id="board" @click="changePanel($event);inputHandler($event)">
      <table>
      ...
      </table>
    </div>
  </div>
</template>
<script>
  export default{
      data () {
          return{
              cacheArr:[], //显示算式
              inputData:'', //缓存输入数值
              preType:'num', //上一个输入类型
              oprStack:[], //操作符栈
              numStack:[], //操作数栈
              calculated:0, //连续计算和重新计算等逻辑需要的标志
              inputShow: 0, //inputData 有时作为输入有时作为输出,需要一个标志
              errorOccurred: 0 //错误标志

          }
      },
      computed:{
          cacheStr() {
              ...
              return this.cacheArr.join("");
          }
      },
      methods: {
          /** 初始化 */
          init(){
              ...
          },

          /** 显示处理 */
          changePanel(e){
            ...
          },

          /** 输入处理 */
          inputHandler (e) {
              ...

              //重新计算判断:1. 上次计算后输入 num 或 opr0; 2. 上次计算结果是 NaN;
              if(...){
                  this.init();
              }

              //继续计算判断:1. 上次计算后输入 opr1 或 opr2
              if(...){
                  //主要处理显示的部分
                  ...
              }

              // inputData 从显示模式调整为输入模式
              ...

              //处理数字-----------------------------------------
              if(type === 'num'){
                  ...
              }

              //处理管理级操作符---------------------------------
              if(type==='opr0'){
                  ...

              }

              //处理其他操作符----------------------------------
              if(type==='opr1' || type==='opr2'){
                  //查看寄存器是否有数据
                  ...

                  //容错机制
                  //1. 如果输入二元操作符-等号,则删掉二元操作符
                  //2. 如果连续输入两次二元操作符,则删掉前一个
                  ...

                  //处理
                  if(value==='equals')
                  {
                      this.oprStack.push({type:type, value:value, level:level});
                      this.preCalculate();
                      this.calculated = 1;
                  }
                  else{
                      this.oprStack.push({type:type, value:value, level:level});
                      this.calculated = 0;
                  }

              }

              //保存等号前的最后一个输入类型--------------------
              ...

          },

          /** 计算预处理 */
          preCalculate () {

              //计算
              this.calculate(this.oprStack, this.numStack);

              //显示结果数据
              ...
          },

          /** 计算过程 */
          calculate(oprStack, numStack){
              //对操作符栈和数值栈进行计算,考虑四则运算的优先级
              ...
          },

          /** 具体计算函数 */
          ...
      }

  }
</script>
<style>
 ...
</style>


大体思路就是这样,一个计算器应该保持简单、直观的使用方式,以免造成用户的困惑。

比如说,自带的计算器里面,上一次计算结果既在显示屏上,也在数值栈中,当用户进行“继续计算”时,输入一个二元运算符,紧接着输入一个等号,计算器会把当前显示屏的数值当做第二个操作数,但这可能不是用户想要的,因为他并没有输入第二个操作数。

在 po主的计算器中,把最后一个输入是二元运算符这种情况当作误操作,自动去掉,以免造成混淆。


踩坑小记

这是一点题外话,主要是记录一下自己犯的错误,大佬们请忽略~

  1. Unicode 字符值的使用。可以到 Unicode 官网 上查询字符值(16进制),比如说 ÷ 号:00f7。
    在 JavaScript 中使用:\u00f7,在 CSS 中使用:\00f7,在 html 中使用:&井号247;。注意 html 中是10进制噢!这里 po主为了避免 markdown 语法自动转换成除号把 ‘#’ 改成了 ‘井号’,各位童鞋自行转换哈…
  2. Vue 文件的 debug 方法。我们知道,使用了 webpack 的项目中,脚本最后要经过编译、压缩、打包,在浏览器的调试工具中是无法调试的。
    一开始我采用的方法是,在源代码要断点的地方输入 debugger,在运行时就可以进入调试模式了。
    后来经老大介绍,有一个叫 Vue DevTools 的工具,各位童鞋可以网上自取。
  3. 跟常识相悖的是:空对象 {} 竟然是真值。所以判断空对象时 if(!nullObj){...} 并不会得到你想要的结果。可以使用 jQuery 中的判断空对象方法:
function isEmptyObject(e) {
    var t;  
    for (t in e)  
    return !1;  
    return !0
}
  1. 由于存在 NaN 这个神奇的毒瘤,以及 Infinity 这样的值,所以判断一个变量是否数值的方法:
function isNumber(value){
    return typeof value === 'number' && isFinite(value);
}
  1. 在 Vue 中,可以在你的方法中访问计算属性,但不要试图去更改它,因为没用。在下次使用该计算属性时,它依然会调用自身的方法来计算。

转载于:https://www.cnblogs.com/ppJuan/p/7141068.html

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以帮你完成这个任务。 首先,你需要在组件中定义两个数据项,分别用来存储输入的两个数字。然后,你可以在模板中添加两个输入框和一个选择框,用来输入数字和选择操作符。你还需要添加一个按钮,用来触发计算。最后,你可以在模板中添加一个区域,用来显示计算结果。代码如下: ```html <template> <div> <input type="number" v-model="firstNumber"> <select v-model="operator"> <option value="+">+</option> <option value="-">-</option> <option value="*">*</option> <option value="/">/</option> </select> <input type="number" v-model="secondNumber"> <button @click="calculate">计算</button> <p>结果:{{ result }}</p> </div> </template> <script> export default { data() { return { firstNumber: 0, secondNumber: 0, operator: '+' } }, computed: { result() { switch (this.operator) { case '+': return this.firstNumber + this.secondNumber; case '-': return this.firstNumber - this.secondNumber; case '*': return this.firstNumber * this.secondNumber; case '/': return this.firstNumber / this.secondNumber; default: return 0; } } }, methods: { calculate() { // 什么也不做,计算属性会自动更新 } } } </script> ``` 现在,你可以在浏览器中打开这个组件,并测试你的简易计算器了。注意,这个计算器没有做任何输入验证和异常处理,只是为了演示计算属性的用法,使用时请自行添加输入验证和异常处理的代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值