1. 程式人生 > >vue.js實現一個計算器

vue.js實現一個計算器

這裡寫圖片描述

為了學習vue.js,把一個基於js實現的計算器轉換為vue.js單頁應用模式。

此次實操旨在學會運用vue.js,不注重計算器的樣式,邏輯

先簡單的看一下基於js實現的計算器是怎樣的

1、html

//只擷取body裡面的內容
<body>
<div id="calcuator">
    <input type="text" id="input-box" value="0" size="21" maxlength="21" readonly="readonly" />
    <div id="btn-list">
        <div
onclick="operator('clear')" class=" btn-30 btn-radius color-red clear-marginleft">
C</div> <div onclick="operator('opposite')" class=" btn-30 btn-radius color-blue">+/-</div> <div onclick="operator('percent')" class=" btn-30 btn-radius color-blue">%</div> <div
onclick="operator('backspace')" class=" btn-70 btn-radius color-red font-14">
</div> <div onclick="typetoinput('7')" class=" btn-30 btn-radius clear-marginleft">7</div> <div onclick="typetoinput('8')" class=" btn-30 btn-radius">8</div> <div onclick
="typetoinput('9')" class=" btn-30 btn-radius">
9</div> <div onclick="operator('plus')" class=" btn-30 btn-radius color-blue font-14">+</div> <div onclick="operator('minus')" class=" btn-30 btn-radius color-blue font-14">-</div> <div onclick="typetoinput('4')" class=" btn-30 btn-radius clear-marginleft">4</div> <div onclick="typetoinput('5')" class=" btn-30 btn-radius">5</div> <div onclick="typetoinput('6')" class=" btn-30 btn-radius">6</div> <div onclick="operator('multiply')" class=" btn-30 btn-radius color-blue font-14">×</div> <div onclick="operator('divide')" class=" btn-30 btn-radius color-blue font-12">÷</div> <div onclick="typetoinput('1')" class=" btn-30 btn-radius clear-marginleft">1</div> <div onclick="typetoinput('2')" class=" btn-30 btn-radius">2</div> <div onclick="typetoinput('3')" class=" btn-30 btn-radius">3</div> <div onclick="operator('pow')" class=" btn-30 btn-radius color-blue font-14">ײ</div> <div onclick="operator('sqrt')" class=" btn-30 btn-radius color-blue font-12"></div> <div onclick="typetoinput('0')" class=" btn-70 btn-radius clear-marginleft">0</div> <div onclick="typetoinput('.')" class=" btn-30 btn-radius">.</div> <div onclick="operator('result')" class=" btn-70 btn-radius color-red font-14">=</div> </div> </div> </body>

可以看到這裡用的是傳統的div+css3進行佈局,這讓我聯想到了vue裡面的元件模式,接下里我會對這裡開始動手,把對應的模組以元件的模式拆出來

2、js

// JavaScript Document
document.oncontextmenu=new Function("event.returnValue=false;");
document.onselectstart=new Function("event.returnValue=false;");
var _string=new Array();
var _type;
//點選數字鍵呼叫的方法
function typetoinput(num)
{
    .....
}
//點選操作鍵呼叫的方法
function operator(type)
{
    .....
}
//用於計算結果
function result(value)
{
    .....
}
//用於判讀是否是一個數字鍵
function checknum(inputvalue)
{
    .....
}


這裡的js都是在html裡面通過on-click事件方法進行呼叫的,這裡可以想到vue裡面的事件繫結機制,我們可以把方法寫在 vue模型裡面,再繫結到事件裡面去

3、改造

1 首先,原來的計算方式是通過全域性的 _string, _type 記錄狀態,輸出框的狀態是通過<input> 標籤的name與value進行記錄的,因此,我們可以通過vue裡面的 data繫結來定義這些需要用到的變數,使用一個物件來代替原先對input屬性的引用

var calculator = new Vue({
    el:'#calculator',
    data:{
        inputShow:{
            value:'0',
            name:''
        },
        string:[],
        type:''
    },
    ......

2 定義元件,把原來的主框體拆成兩個子元件,分別為顯示框與鍵盤,通過元件的父子數值繫結,把父元件中的 inputShow 賦給子元件,再通過計算屬性把其中的value 展示出來,具體鍵盤裡面的鍵是直接寫html父標籤裡面的,因為我覺得此時的css的靜態的,所以不抽離出來,使用<slot> 佔位呈現。

html

<body>
//主元件
<div id="calculator">
//下面兩個分別為子元件
    <!--顯示框-->
    <input-box v-bind:input-show="inputShow">

    </input-box>
    <btn-list>
        <div v-on:click="operator('clear')" class=" btn-30 btn-radius color-red clear-marginleft">C</div>
        <div v-on:click="operator('opposite')" class=" btn-30 btn-radius color-blue">+/-</div>
        <div v-on:click="operator('percent')" class=" btn-30 btn-radius color-blue">%</div>
        <div v-on:click="operator('backspace')" class=" btn-70 btn-radius color-red font-14">←</div>
        <div v-on:click="typetoinput('7')" class=" btn-30 btn-radius clear-marginleft">7</div>
        <div v-on:click="typetoinput('8')" class=" btn-30 btn-radius">8</div>
        <div v-on:click="typetoinput('9')" class=" btn-30 btn-radius">9</div>
        <div v-on:click="operator('plus')" class=" btn-30 btn-radius color-blue font-14">+</div>
        <div v-on:click="operator('minus')" class=" btn-30 btn-radius color-blue font-14">-</div>
        <div v-on:click="typetoinput('4')" class=" btn-30 btn-radius clear-marginleft">4</div>
        <div v-on:click="typetoinput('5')" class=" btn-30 btn-radius">5</div>
        <div v-on:click="typetoinput('6')" class=" btn-30 btn-radius">6</div>
        <div v-on:click="operator('multiply')" class=" btn-30 btn-radius color-blue font-14">×</div>
        <div v-on:click="operator('divide')" class=" btn-30 btn-radius color-blue font-12">÷</div>
        <div v-on:click="typetoinput('1')" class=" btn-30 btn-radius clear-marginleft">1</div>
        <div v-on:click="typetoinput('2')" class=" btn-30 btn-radius">2</div>
        <div v-on:click="typetoinput('3')" class=" btn-30 btn-radius">3</div>
        <div v-on:click="operator('pow')" class=" btn-30 btn-radius color-blue font-14">ײ</div>
        <div v-on:click="operator('sqrt')" class=" btn-30 btn-radius color-blue font-12">√</div>
        <div v-on:click="typetoinput('0')" class=" btn-70 btn-radius clear-marginleft">0</div>
        <div v-on:click="typetoinput('.')" class=" btn-30 btn-radius">.</div>
        <div v-on:click="operator('result')" class=" btn-70 btn-radius color-red font-14">=</div>
    </btn-list>
</div>
<script type="text/javascript" src="js/my-app.js"></script>
</body>

vue

  ....
  components:{
        'input-box':{
            props:['inputShow'],
            computed: {
                value:function () {
                    return this.inputShow.value
                }
            },
            template:'<input id="input-box" type="text" size="21" maxlength="21" v-model="value" readonly="readonly">'
        },
        'btn-list':{
            template:'<div id="btn-list"><slot></slot></div>'
        }
    },
    .....

3、根據html裡面可以看到我們使用了v-on:click="...." 對div裡面的onclick事件方法進行繫結,所以,我們只需要把原專案裡面的函式寫到vue裡面然後再繫結到事件上面就行了

js

//具體引數詳見上面
methods:{
        result:function(value){
            ....
        },
        typetoinput:function(num){
           ....
        },
        checknum:function(inputvalue){
           ....
        }

    }