vue.js實戰——購物車練習(包含全選功能)


vue.js實戰第5章 54頁的練習1

直接放代碼好了,全選的部分搞了好久,代碼好像有點啰嗦,好在實現功能了(*^▽^*)

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="index.css">
</head>
<body>
    <div id="app" v-cloak>
        <template v-if="list.length">
            <table>
                <thead>
                    <tr>
                        <th>
                            <input type="checkbox" v-model="checkAll">全選
                        </th>
                        <th>商品名稱</th>
                        <th>商品單價</th>
                        <th>購買數量</th>
                        <th>操作</th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="(item,index) in list">
                        <!-- <td>{{index+1}}</td> -->
                        <td><input type="checkbox" :checked="item.check" @click="isAll(index)"> {{item.check}}</td>
                        <td>{{item.name}}</td>
                        <td>{{item.price}}</td>
                        <td>
                            <button @click="handleReduce(index)" :display="item.count===1">-</button>
                                {{item.count}}
                            <button @click="handleAdd(index)">+</button>
                        </td>
                        <td>
                            <button @click="handleRemove(index)">移除</button>
                        </td>
                    </tr>
                </tbody>
            </table>
            <div>總價:¥{{totalPrice}}</div>
        </template>    
        <div v-else>
            購物車為空
        </div>
    </div>
    <script src="../vue.js"></script>
    <script src="index.js"></script>
</body>
</html>

JS:

var app=new Vue({
    el:'#app',
    data:{
        list:[
            {
                id:1,
                name:'iPhone 7',
                price:6288,
                count:1,
                check:false
            },{
                id:2,
                name:'iPad Pro',
                price:5888,
                count:1,
                check:false
            },{
                id:3,
                name:'MacBook Pro',
                price:21488,
                count:1,
                check:false
            }
        ],
        checkAll:false,
        smallHand:false
    },
    computed:{
        totalPrice:function(){
           this.newList=this.list.filter(function(item){
                    if(item.check){
                        return item;
                    }
            });
            var total=0;
            for(var i=0;i<this.newList.length;i++){
                var item=this.newList[i];
                total+=item.price*item.count;
            }
            return total.toString().replace(/\B(?=(\d{3})+$)/g,',');//匹配后面已3個數字結尾的非單詞邊界,換成“,”
            /* replace:
                用於在字符串中用一些字符替換另一些字符,或替換一個與正則表達式匹配的子串
                \B  :匹配非單詞邊界
                (red|blue|green):查找任何指定的選項
                ?=n :匹配任何其后緊接指定字符串n的字符串(n量詞)    提供后面的n找?
                \d  :查找數字
                n{X}:匹配包含X個n的序列字符串
                \d{3}:匹配含有3個數字的字符串
                n$  :匹配任何結尾為n的字符串
                n+  :匹配任何包含至少一個n的字符串
                (\d{3})+$   :匹配至少一個已含有3個數字字符串結尾的字符
             */    
        }
    },
    methods:{
        handleReduce:function(index){
            if(this.list[index].count===1) return;
            this.list[index].count--;
        },
        handleAdd:function(index){
            this.list[index].count++;
        },
        handleRemove:function(index){
            this.list.splice(index,1);
        },
        isAll:function(index){
            console.log(this.list[index].check);
            var indexItem=this.list[index];
            
            indexItem.check=!indexItem.check;
            var num=0;
            for(var i=0;i<this.list.length;i++){
                var item=this.list[i];
                if(item.check){
                    num++;
                }else{
                    num--;
                }
            }
            console.log(num);////(選中了最后一個)3-全部勾選-勾選全選     (之前全部勾選,取消了任意一個勾選) 1-取消全選的勾選   
           if(num==3||(num==1&&indexItem.check==false)){ //考慮不周全 this.checkAll=indexItem.check;
                this.smallHand=true;
            }
        }
    },
    watch:{
        checkAll:function(){
            if(this.smallHand){

            }else{
                for(var i=0;i<this.list.length;i++){
                    this.list[i]['check']=this.checkAll;
                }
            }
            this.smallHand=false;           
        }
    }
})

JS部分補充說明:上面的代碼在刪除時沒辦法繼續“全選”的同步,而且這里數字被寫死是錯誤的(   if(num==3||(num==1&&indexItem.check==false)){    )。

更新改進后的代碼如下:

var app=new Vue({
    el:'#app',
    data:{
        list:[
            {
                id:1,
                name:'iPhone 7',
                price:6288,
                count:1,
                check:false
            },{
                id:2,
                name:'iPad Pro',
                price:5888,
                count:1,
                check:false
            },{
                id:3,
                name:'MacBook Pro',
                price:21488,
                count:1,
                check:false
            }
        ],
        checkAll:false,
        smallHand:false
    },
    computed:{
        totalPrice:function(){
           this.newList=this.list.filter(function(item){
                    if(item.check){
                        return item;
                    }
            });
            var total=0;
            for(var i=0;i<this.newList.length;i++){
                var item=this.newList[i];
                total+=item.price*item.count;
            }
            return total.toString().replace(/\B(?=(\d{3})+$)/g,',');//匹配后面已3個數字結尾的非單詞邊界,換成“,”
            /* replace:
                用於在字符串中用一些字符替換另一些字符,或替換一個與正則表達式匹配的子串
                \B  :匹配非單詞邊界
                (red|blue|green):查找任何指定的選項
                ?=n :匹配任何其后緊接指定字符串n的字符串(n量詞)    提供后面的n找?
                \d  :查找數字
                n{X}:匹配包含X個n的序列字符串
                \d{3}:匹配含有3個數字的字符串
                n$  :匹配任何結尾為n的字符串
                n+  :匹配任何包含至少一個n的字符串
                (\d{3})+$   :匹配至少一個已含有3個數字字符串結尾的字符
             */    
        }
    },
    methods:{
        handleReduce:function(index){
            if(this.list[index].count===1) return;
            this.list[index].count--;
        },
        handleAdd:function(index){
            this.list[index].count++;
        },
        handleRemove:function(index){
            this.list.splice(index,1);
            var num=0;
            var allNum=0;
            for(var i=0;i<this.list.length;i++){
                var item=this.list[i];
                allNum++;
                if(item.check){
                    num++;
                }else{
                    num--;
                }
            }
            if(num==allNum){
                this.checkAll=true;
            }else{
                this.checkAll=false;
            }
        },
        isAll:function(index){
            console.log(this.list[index].check);
            var indexItem=this.list[index];
            
            indexItem.check=!indexItem.check;
            var num=0;
            var allNum=0;
            for(var i=0;i<this.list.length;i++){
                var item=this.list[i];
                allNum++;
                if(item.check){
                    num++;
                }else{
                    num--;
                }
            }
            console.log(num);////(選中了最后一個)3-全部勾選-勾選全選     (之前全部勾選,取消了任意一個勾選) 1-取消全選的勾選   
        //    if(num==3||(num==1&&indexItem.check==false)){     這里不能寫死的傻瓜
        if(num==allNum||(num==(allNum-2)&&indexItem.check==false)){
                this.checkAll=indexItem.check;
                this.smallHand=true;
            }
        }
    },
    watch:{
        checkAll:function(){
            if(this.smallHand){

            }else{
                for(var i=0;i<this.list.length;i++){
                    this.list[i]['check']=this.checkAll;
                }
            }
            this.smallHand=false;           
        }
    }
})

css:

[v-cloak] {
  display: none;
}
table {
  border: 1px solid #e9e9e9;
  border-collapse: collapse;
  border-spacing: 0;
  empty-cells: show;
}
table th,
table td {
  padding: 8px 16px;
  border: 1px solid #e9e9e9;
  text-align: left;
}
table th {
  background: #f7f7f7;
  color: #5c6b77;
  font-weight: 600;
  white-space: nowrap;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM