使用Vue创建计算器

lazyladybug 发布于6天前 阅读41次
0 条评论

学习Vue有一段时间了,但真正的实战并不是很多。师父告诉我,要学好就得多动手。为了能把动手写的案例有一个集中的地方放置,我在Github上创建了一个仓库 VueStudy 。这里将会不断的添加一些练习过的案例,如果你感兴趣的话,欢迎提交你写过的案例。

今天我们来写一个案例: 使用Vue创建计算器Github有对应的示例代码 。如果你想在本地运行,看到对应的效果,可以把这个项目下载到你的本地,然后进入对应的目录,执行下面的命令:

npm i
npm run dev

然后在浏览器地址中输入 http://localhost:8080 就能看到了。接下来我们来看看怎么用Vue创建这个计算器。

今天的目标

今天的目标,就是使用Vue做一个计算器,如下图所示:

使用Vue创建计算器

这个计算器我们有两个版本,一个简单版本:

使用Vue创建计算器

另一个是高级版本:

使用Vue创建计算器

当我们使用Vue把计算器做好之后,可以帮你执行一些任务。而通过这个教程,可以学到Vue一些相关知识:

  • 处理用户输入
  • 使用模板语法将数据渲染到DOM
  • 熟悉处理数据的基本指令
  • 创建Vue实例

一些准备工作

虽然说我们这里是使用Vue来创建一个计算器,但始终还是脱离不开JavaScript方面的知识。也就是说,有关于计算器功能方面的实现,还是需要通过JavaScript来实现。如果你和我一样,JavaScript知识比较单薄的话,建议先补充一些有关这方面的知识。个人建议你可以看看 @dunizb写的一个计算器 ,或者学习一下 math.js 库中的一些知识。接下来的内容假设你已经对这方面有所了解,可以使用JavaScript完成计算器相关的知识。

回到Vue的世界中来。使用Vue创建计算器,也相当于我们开始一个新项目,那么在Vue中,创建这样的项目有多种方式。或者说创建我们的计算器有多种方式。比如前面《Vue的运行环境》文中提到的。可以在一个单独的文件中使用Vue,也可以在在线的Codepen中创建。不过我们今天采用的是一种新的方式,采用Vue官方提供的项目构建工程 Vue CLI

要正常使用Vue CLI得先确保你的环境中已经安装了Node和NPM。然后在你的命令终端执行:

npm i vue-cli -g

也就是在本地电脑中全局安装Vue CLI。假设你按上面的命令已成功安装好了,那么接下来通过其构建我们需要的Vue项目。

进入你的工作环境,然后执行:

vue init webpack vue-calculator

这样我们就创建了 vue-calculator 项目,然后进入这个项目,安装项目所需的依赖关系:

cd vue-calculator
npm i

这样在你的本地,可以看到项目对应的目录结构:

使用Vue创建计算器

而且项目所需要的依赖关系都在 package.json 文件中。接下来运行:

npm run dev

在浏览器中运行 http://localhost:8080/ 就可以浏览项目的效果。

Vue项目

通过Vue CLI构建的Vue项目,其入口文件是 main.js 。在这个文件中引入Vue和创建Vue实例:

import Vue from 'vue'
import App from './App'

new Vue({
    el: '#app',
    template: '<App/>',
    components: { App }
})

上面的代码是引入了 vue 和一个 App 组件,然后通过下面的方式创建了一个Vue实例,然后将Vue控制的部分视图挂载在 el 属性上进行跟踪。而 el 属性值对应的是 index.html 文件中的 div#app 元素:

<div id="app>
    <!-- HTML都将会塞到这里 -->
</div>

创建Vue组件

我们的目标是创建一个计算器,那么我们把这个计算器称作Vue的一个组件。所以我们首要的条件就是先创建一个组件,我们这里一个叫 calculator 组件。在项目中,进入 /src/components 目录中创建一个 calculator.vue 文件。我们有关于计算器相关的东西都将放在这个文件中。他的格式一般如下:

<template>
    <div>
        <!-- 需要用一个容器包裹组件中用到的所有元素 -->
    </div>
</tempalte>

<script>
    export default {
        // 逻辑代码写在这
    }
</script>

<style>
    /* 组件样式写在这里 */
</sytle>

也就是说一个组件包含三个部分:

  • <template> :用来放置组件相关的模板
  • <script> :用来放置组件逻辑相关的代码,通过 export default{} 输出
  • <style> :用来放置组件相关的样式

创建组件之后,在 App.vue 中引入创建好的组件:

<template>
    <div id="app">
        <Calculator />
    </div>
</template>

<script>
    import Calculator from './components/calculator'

    export default {
        name: 'app',
        components: {
            Calculator
        }
    }
</script>

<style>
    // ....
</style>

这样整个链路就通了。当然,现在这个时候,你在浏览器中还看不到任何的东西。那是因为我们的 calculator.vue 中还未写任何有关于组件相关的东西。接下来我们就专心写组件相关的东西。

添加计算器需要的元素

计算器首先需要一个输入屏,在这里使用 input 来表示。而他的功能是,用户点击计算器中的按钮时, input 中对应的 value 值会有更新。这需要使用到前面所介绍的 v-model 指令进行数据双向绑定。在 input 元素中通过 v-model 绑定 data 数据对象中的 current 属性:

<div class="results">
    <input class="input" v-model="current">
</div>

视图绑定的值存储在 data 对象中,如下所示:

export default {
    name: 'Calculator',
    data () {
        return{ 
            current: ''
        }
    }
}

接下来我们需要给计算器添加按钮。这里我们使用 button 元素来做。

<button class="button">7</button>

在Vue中,允许我们在实例中创建方法,提供无缝的事件处理和状态更改触发器。我们可以通过 v-on (简写 @ )指令在我们的HTML中元素绑定对应的事件。在这里我们使用的是 click 事件,而这个事件绑定的是一个叫 press 的方法:

<button class="button" @click="press">7</button>

对应的脚本中,添加 methods 方法:

export default {
    name: 'Calculator',
    data () {
        return{ 
            current: ''
        }
    },
    methods: {
        press: function(event) {
            // 计算器按钮的click事件
        }
    }
}

在 methods 中我们添加了 press 函数,这个函数将处理计算器按钮的点击的一些事情。具体做些什么事情,咱们先别说,后面的内容将会完善这部分。

文章开头提到过,我们的计算器分为两个部分,一个是简易版的计算器,另一个是高级版的计算器。在Vue中我们可以通过 v-if (当然也可以使用 v-show )来判断显示哪个版本。这个时候需要在 data 中创建一个 changeMode 属性,当这个属性的值为 true 时显示简易版计算器,反则为 false 时显示高级版本计算器。

<div class="mode" v-if="changeMode">
    <!-- 简易版本计算器 -->
    <button class="button" @click="press">7</button>
    ...
    <button class="button equal-sign" @click="press">=</button>  
</div>
<div class="mode" v-else>
    <!-- 高级版本计算器 -->
    <button class="button" @click="press">7</button>
    ...
    <button class="button equal-sign" @click="press">=</button>  
</div>

export default {
    name: 'Calculator',
    data () {
        return{ 
            current: '',
            changeMode: true
        }
    },
    methods: {
        press: function(event) {
            // 计算器按钮的click事件
        }
    }
}

这个时候,我们需要一个类似 button 一样的东东,能触发显示哪个版本的计算器:

<button @click="changeModeEvent" class="toggle-button">
    <p v-if="changeMode">Show Advanced Mode     ⚈</p>
    <p v-else>Show Basic Mode     ⚆</p>
</button>

同样的,在 button 上通过 v-on 绑定 changeModeEvent 方法,这个方法主要任务就是修改 changeMode 的值。这个方法和 press 方法一样,都将放置在 methods:{} 中。这个时候你看到的效果如下:

上面我们看到的是简易版本的效果。如果 app.changeMode 换成 false 时,看到的是高级版本的。

使用Vue创建计算器

没有样式,看得实在难受。这个时候在 <style> 中添加样式,我们的计算器就会好看得多:

添加JavaScript

现在万事都具备了,就欠东风了。为了更好的完善计算器功能,在Vue中 methods:{} 中的 press 和 changeModeEvent 中添加对应的功能代码:

export default {
    name: 'Calculator',
    data () {
        return{ 
        current: '',
        changeMode: true
        }
    },
    methods: {
        press: function (event) {
            let me = this
            let key = event.target.textContent

            if (
                key != '=' && 
                key != 'C' &&
                key != '*' &&
                key != '/' &&
                key != '√' &&
                key != "x ²" &&
                key != "%" &&
                key != "<=" && 
                key != "±" && 
                key != "sin" && 
                key != "cos" && 
                key != "tan" && 
                key != "log" && 
                key != "ln" && 
                key != "x^" && 
                key != "x !" && 
                key != "π" && 
                key != "e" && 
                key != "rad" && 
                key != "∘"
            ) {
                me.current += key

            } else if (key === '=') {

                if ((me.current).indexOf('^') > -1) {
                    let base = (me.current).slice(0, (me.current).indexOf('^'))
                    let exponent = (me.current).slice((me.current).indexOf('^') + 1)
                    me.current = eval('Math.pow(' + base + ',' + exponent + ')')
                } else {
                    me.current = eval(me.current)
                }

            } else if (key === 'C') {

                me.current = ''

            } else if (key === '*') {

                me.current += '*'

            } else if (key === '/') {

                me.current += '/'

            } else if (key === '+') {

                me.current += '+'

            } else if (key === '-') {

                me.current += '-'

            } else if (key === '±') {

                if ((me.current).charAt(0) === '-') {
                    me.current = (me.current).slice(1)
                } else {
                    me.current = '-' + me.current
                }

            } else if (key === '<=') {

                me.current = me.current.substring(0, me.current.length - 1)

            } else if (key === '%') {

                me.current = me.current / 100

            } else if (key === 'π') {

                me.current = me.current * Math.PI

            } else if (key === 'x ²') {

                me.current = eval(me.current * me.current)

            } else if (key === '√') {

                me.current = Math.sqrt(me.current)

            } else if (key === 'sin') {

                me.current = Math.sin(me.current)

            } else if (key === 'cos') {

                me.current = Math.cos(me.current)

            } else if (key === 'tan') {

                me.current = Math.tan(me.current)

            } else if (key === 'log') {

                me.current = Math.log10(me.current)

            } else if (key === 'ln') {

                me.current = Math.log(me.current)

            } else if (key === 'x^') {

                me.current += '^'

            } else if (key === 'x !') {

                let number = 1
                if (me.current === 0) {
                    me.current = '1'
                } else if (me.current < 0) {
                    me.current = NaN
                } else {
                    let number = 1
                    for (let i = me.current; i > 0; i--) {
                        number *= i
                    }
                    me.current = number
                }

            } else if (key === 'e') {

                me.current = Math.exp(me.current)

            } else if (key === 'rad') {

                me.current = me.current * (Math.PI / 180)

            } else if (key === '∘') {

                me.current = me.current * (180 / Math.PI)

            }
        },
        changeModeEvent: function() {
            let me = this
            me.changeMode = !me.changeMode
        }
    }
}

整体代码就不做过多阐述了。我想大家一看就能明白其中的意思。当然你也可以把每个功能提取出来,成为一个函数,比如:

//our ' C ' button
function clear() {
    app.current = "";
}

//our ' <= ' button
function backspace() {
    app.current = app.current.substring(0, app.current.length - 1);
}

这个时候,你浏览器将看到一个完整的计算器效果:

体验一下吧!

总结

这篇文章主要以创建一个计算器为例,来学习Vue相关的知识。在这篇文章中我们学习了怎么使用Vue CLI这样的构建工具创建一个Vue项目。又是怎么通过一个单独的文件创建Vue组件,并且将组件调用。同时在完成整个Vue版本的计算器,我们还使用了 v-on 指令来绑定事件, v-model 实现数据双向绑定, v-if 控制模板的显示与否等。当然还学习了怎么在 methods 中创建方法,让其无缝的事件处理和状态更改触发器。

通过这个实例,再次感觉到与Vue一起工作带来的优势。而我们这个示例的效果可以在 Codepen 上看到(采用另外创建计算器的方式),也可以在 Github上查看代码 。由于作者是Vue的初学者,如果文章中有不对之处,还请各路大婶指正。如果你有更好的实现方案或思路,欢迎在下面的评论中与我们一起分享。

特别声明:这篇文章中的计算器示例效果是根据 @Raphael Ugwu 的教程中 案例 写的。

使用Vue创建计算器

大漠

常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《 图解CSS3:核心技术与案例实战 》。

查看原文: 使用Vue创建计算器

  • redmouse
  • smallwolf
  • smallpanda
  • blackpanda
  • organicduck
  • yellowpeacock
  • purpleladybug
  • tinyelephant
需要 登录 后回复方可回复, 如果你还没有账号你可以 注册 一个帐号。