Vue.js实战梁笔记02(第3-5章)

1、计算属性

当表达式过程的时候,不如使用函数,如何使用函数呢,使用methods是一种,使用计算属性也是一种方式。

所有的计算属性都是以函数的形式卸载vue实例内的computed选项内,最终返回计算后的结果
对实例内的数据的应用注意要使用this关键字

<body>   
<div id="app">
       {{mycompute}} </div> <script type="text/javascript">
   
   var app=new Vue({
       el:"#app",
       data:{
           show:true,
           number1:100,
           number2:1200
           
       },
       //方法,过滤器等单独做一个对象来存储
       methods:{
           handleClose:function(){
               this.show=false;//这个show是自定义的对象
           }
       },
       computed:{
           mycompute:function(){
               return this.number1+this.number2;
           }
       }
        }); </script> 
 </body>
2、计算属性用法

在一个计算属性里可以完成各种复杂的逻辑,包括运算,函数调用等,只要最终返回一个结果就可以。

计算属性还可以依赖多个vue实例的数据,只要其中任一数据变化,计算属性就会重新执行,视图也会更新。

<body>  
<div id="app">
    {{totalPrice}}
</div>
<script type="text/javascript">

var app=new Vue({
    el:"#app",
    data:{
        package1:[
            {
               goods:'iphone',
               price: 3000,
               count:2
            },
            {
               goods:'ipad',
               price: 4000,
               count:3
            }
        ],
        package2:[
            {
                goods:'apple',
                price:5,
                count:5
            },
            {
                goods:'banana',
                price:12,
                count:15
            }
        ]
        
    },
    //方法,过滤器等单独做一个对象来存储
    methods:{
        handleClose:function(){
            this.show=false;//这个show是自定义的对象
        }
    },
    computed:{
        totalPrice:function(){
            var wholePrice=0;
            for(var i=0; i<this.package1.length; i++){
                wholePrice+= this.package1[i].price*this.package1[i].count
            }
            
            for(var i=0; i<this.package2.length; i++){
                wholePrice+= this.package2[i].price*this.package2[i].count
            }

            return wholePrice;
        }
    }
    
});
</script>
</body>
3、计算属性的getter和setter
<body>  
<div id="app">
    {{fullName}}
</div>
<script type="text/javascript">

var app=new Vue({
    el:"#app",
    data:{
        firstName:'jack',
        secondeName:'ma'
        
    },
    //方法,过滤器等单独做一个对象来存储
    methods:{
        handleClose:function(){
            this.show=false;//这个show是自定义的对象
        }
    },
    computed:{
        fullName:{
            get:function(){
                return this.firstName+' '+this.secondeName;
            },
            set:function(newValue){
                var namearray=newValue.split(' ');
                this.firstName=namearray[0];
                this.secondeName=namearray[namearray.length-1];
                
            }
        }
    }
    
});
</script>

计算文本除了使用文本插值,还经常用于动态地设置元素的样式明湖曾class和内联样式style。

4、计算属性的getter和setter

计算属性可以依赖其他计算属性
计算属性不仅可以依赖当前vue实例的数据,还可以依赖其他实例的数据。
通过vue实例名.对象名进行访问

<body>  
<div id="app1"></div>
<div id="app2">
    {{reversedText}}
</div>
<script type="text/javascript">
var app1=new Vue({
        el:"#app1",
        data:{
            text:'1234,5678'
        }
    }
);

var app2=new Vue({
    el:"#app2",
    data:{
      
    },
   
    computed:{
        reversedText:function (){
            return app1.text.split(",").reverse().join(',');
        }
    }
});


</script>
</body>
5、计算属性缓存

遍历大数组和大量计算是应当使用计算属性,他可以缓存,如果数据不练不大,建议使用menthods里的方法function,每次渲染都会被调用,且还可以使用参数

6、v-bind绑定class与style

dom元素经常会动态绑定类名或class样式。

<html>
    <head>
    <style type="text/css">
    .test{color:red}
   
    </style>
    <script src="vue.js"></script>
    </head>
<body>  
<div id="app">
    <div :class="{'test':isactive}">测试v-bind绑定类名</div>
</div>
<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            isactive:true,
        }
    }
);

</script>
</body>
</html>

绑定多个属性,动态切换class,且可以和普通class共存

<html>
    <head>
    <style type="text/css">
    .test{color:red; width: 200px; height: 30px;}
    .urtest{border: 2px solid black; width: 200px; height: 30px;}
    .mytest{background-color: yellow;}
    </style>
    <script src="vue.js"></script>
    </head>
<body>  
<div id="app">
    <div :class="{'test':isactive,'urtest':uractiv}" class="mytest">测试v-bind绑定类名</div>
</div>
<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            isactive:true,
            uractiv:true
        }
    }
);

</script>
</body>
</html>

当一个容器同时具有多个类名时,也会具备各个类名所代表的所有样式

当需要绑定的类名过长或者逻辑较为复杂的时候,可以绑定一个计算属性。

<html>
    <head>
    <style type="text/css">
    .test{color:red; width: 200px; height: 30px;}
    .urtest{border: 2px solid black; width: 200px; height: 30px;}
    .mytest{background-color: yellow;}
    </style>
    <script src="vue.js"></script>
    </head>
<body>  
<div id="app">
    <!--下面类名时用了绑定,且使用的事计算属性-->
    <div :class="mycompute" >测试v-bind绑定类名</div>
</div>
<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            isactive:true,
            uractiv:true
        },
        computed:{
            mycompute:function (){
                return 'test urtest';
            }
        }
    }
);

</script>
</body>
</html>
7、数组语法
  • 1、应用多个class的时候,可以使用数组语法,给class绑定一个数组,应用一个class列表。上例是使用一个对象来替代数组
class{类名1:true ofr false,类名2:true ofr false,...}
calss:[类名1,类名2...]
  • 2、当class属性时数组的时候,数组元素是data的对象,通过对象下标访问。不需要使用引号
<html>
    <head>
    <style type="text/css">
    .test{color:red; width: 200px; height: 30px;}
    .urtest{border: 2px solid black; width: 200px; height: 30px;}
    .mytest{background-color: yellow;}
    </style>
    <script src="vue.js"></script>
    </head>
<body>  
<div id="app">
    <!--下面类名时用了绑定,且使用的事计算属性-->
    <div :class="[firstcalss,secondeclass]" >测试v-bind绑定类名</div>
</div>
<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            firstcalss:"test",
            secondeclass:"mytest"
        },
        computed:{
            mycompute:function (){
                return 'test urtest';
            }
        }
    }
);

</script>
</body>
</html>
  • 2、在使用数组语法的时候还可以用三元运算符来切换
<html>
    <head>
    <style type="text/css">
    .test{color:red; width: 200px; height: 30px;}
    .urtest{border: 2px solid black; width: 200px; height: 30px;}
    .mytest{background-color: yellow;}
    </style>
    <script src="vue.js"></script>
    </head>
<body>  
<div id="app">
    <!--下面类名时用了绑定,且使用的事计算属性-->
    <div :class="[isactive ? firstcalss:secondeclass,thirdclass]" >测试v-bind绑定类名</div>
</div>
<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            isactive:false,
            firstcalss:"test",
            secondeclass:"mytest",
            thirdclass:"urtest"
        },
        computed:{
            mycompute:function (){
                return 'test urtest';
            }
        }
    }
);

</script>
</body>
</html>
  • 3、也可以在数组中使用对象语法
<html>
    <head>
    <style type="text/css">
    .test{color:red; width: 200px; height: 30px;}
    .urtest{border: 2px solid black; width: 200px; height: 30px;}
    .mytest{background-color: yellow;}
    </style>
    <script src="vue.js"></script>
    </head>
<body>  
<div id="app">
    <!--下面类名时用了绑定,且使用的事计算属性-->
    <div :class="[{'test':isactive},secondeclass]" >测试v-bind绑定类名</div>
</div>
<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            isactive:true,
            firstcalss:"test",
            secondeclass:"mytest",
            thirdclass:"urtest"
        },
        computed:{
            mycompute:function (){
                return 'test urtest';
            }
        }
    }
);

</script>
</body>
</html>

实际上可是使用data,computed和methods三种方法

8、在组件上使用vue对象

1、先自定义组件
2、在使用自定义组件
3、自定义组件标签上使用vue对象

<html>
    <head>
    <style type="text/css">
    .test{color:red; width: 200px; height: 30px;}
    .urtest{border: 2px solid black; width: 200px; height: 30px;}
    .mytest{background-color: yellow;}
    </style>
    <script src="vue.js"></script>
    </head>
<body>  
<div id="app">
    <!--下面类名时用了绑定,且使用的事计算属性-->
    <my-component :class="{'test':isactive}" ></my-component>
</div>
<script type="text/javascript">
//创建一个叫做my-component的自定义组件
Vue.component('my-component',{
    template:'<p class="article">自定义的组件</p>'
});

var app=new Vue({
        el:"#app",
        data:{
            isactive:true,
            firstcalss:"test",
            secondeclass:"mytest",
            thirdclass:"urtest"
        },
        computed:{
            mycompute:function (){
                return 'test urtest';
            }
        }
    }
);

</script>
</body>
</html>
9、绑定内联样式

使用v-bind:style可以给元素绑定内联样式,方法与class类似,也有对象语法和数组语法,看起来很像直接在元素上写css

<html>
    <head>
    <style type="text/css">
    .test{color:red; width: 200px; height: 30px;}
    .urtest{border: 2px solid black; width: 200px; height: 30px;}
    .mytest{background-color: yellow;}
    </style>
    <script src="vue.js"></script>
    </head>
<body>  
<div id="app">
    <!--下面类名时用了绑定,且使用的事计算属性-->
    <div :style="{'color':color,'border':border,'width':width,'height':height}" >使用内联方式绑定属性</div>
</div>
<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            color:'red',
            border:'1px solid green',
            width:'200px',
            height:'30px',
         
        },
        computed:{
           
        }
    }
);

</script>
</body>
</html>

内联写法如果太长,可以只接写在data,methods或者computed里

<html>
    <head>
    <style type="text/css">
    .test{color:red; width: 200px; height: 30px;}
    .urtest{border: 2px solid black; width: 200px; height: 30px;}
    .mytest{background-color: yellow;}
    </style>
    <script src="vue.js"></script>
    </head>
<body>  
<div id="app">
    <!--下面类名时用了绑定,且使用的事计算属性-->
    <div :style="styles" >使用内联方式绑定属性</div>
</div>
<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            styles:{
                color:'red',
                border:'3px solid green',
                width:'200px',
                height:'30px',
            }
            
         
        },
        computed:{
           
        }
    }
);

</script>
</body>
</html>

应用多个样式的时候可以使用数组语法

<html>
    <head>
    <style type="text/css">
    .test{color:red; width: 200px; height: 30px;}
    .urtest{border: 2px solid black; width: 200px; height: 30px;}
    .mytest{background-color: yellow;}
    </style>
    <script src="vue.js"></script>
    </head>
<body>  
<div id="app">
    <div :style="[stylesA,stylesB]" >使用内联方式绑定属性</div>
</div>
<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            stylesA:{
                color:'red',
              
            },
            stylesB:{
                border:'1px solid green',
                width:'200px',
                height:'30px',
            }
            
         
        },
        computed:{
           
        }
    }
);

</script>
</body>
</html>
10、基本指令v-cloak

不需要表达式,会在vue实例结束编译时从绑定的html元素上移除,经常和css的display:none配合使用

该方法解决慢速下载中出现闪屏的情形,现实中比较少用

<html>
    <head>
    <style type="text/css">
    [v-cloak]{
        display: none;
    }
    </style>
    <script src="vue.js"></script>
    </head>
<body>  
<div id="app" v-cloak>
    {{text}}
</div>
<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            text:"here is some words",
            
         
        }
    }
);

</script>
</body>
</html>
11、v-once单次渲染(静态渲染)

定义他的元素或组件只渲染一次,包括元素或组件的所有子节点。首次渲染后,不在随数据的变化重新渲染,将被视为静态内容,v-once很少用

<body>  
<div id="app" v-cloak>
    <span v-once>{{text}}</span>
    <div v-once>
        <span>{{text}}</span>
    </div>
</div>
<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            text:"here is some words",         
        }
    }
);

</script>
</body>
12、vi-if、v-else-if、v-else条件渲染

更具表达式的值在dom中渲染或销毁元素/组件

<body>  
<div id="app" >
    <div v-if="status===1">when if is true</div>
    <div v-else-if="status==2">when else if is equal</div>
    <div v-else>finally information</div>
</div>
<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            status:3,         
        }
    }
);

</script>
</body>

如果需要一次判断(渲染)多个元素,可以在vue内置的元素上使用条件指令,最终渲染的结果不会包含该元素

<html>
    <head>
    <style type="text/css">
   
    </style>
    <script src="vue.js"></script>
    </head>
<body>  
<div id="app" >
    <template v-if="status===1">
        <p>here are some text</p>
        <p>here are some text</p>
        <p>here are some text</p>

    </template>
</div>
<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            status:1,         
        }
    }
);

</script>
</body>
</html>

vue在渲染元素时,出于效率考虑,会尽可能地复用已有的元素而非重新渲染。

关于< template>标签

  • < template>原生不可见,实际是包含了display:none,在vue中必须被包含在vue绑定的父标签内才能设置可见或者不可见
  • vue实例内部绑定的< template>不可以使用v-show,但可以使用vi-if,v-ifelse,v-else
  • < template>可以使用data,methods和computed的值
    关于这个问题可以参见连接
    复用案例如下:
<body>  
<div id="app" >
    <template v-if="type==='name'">
        <label>用户名:</label>
        <input placeholder="输入用户名"/>
    </template>
    <template v-else>
        <label>邮箱:</label>
        <input placeholder="输入邮箱"/>
    </template>
    <button @click="handleToggleClick">切换输入类型</button>
</div>
<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            type:'name',         
        },
        methods:{
            handleToggleClick:function (){
                this.type=this.type==='name'?'mail':'name';
            }
        }

    }
);

</script>
</body>

如果不想< template>被复用,可以使用vue的key属性。同时key的值应当是唯一的。

<body>  
<div id="app" >
    <template v-if="type==='name'">
        <label>用户名:</label>
        <input placeholder="输入用户名" key='name-input' />
    </template>
    <template v-else>
        <label>邮箱:</label>
        <input placeholder="输入邮箱" key='mail-input'/>
    </template>
    <button @click="handleToggleClick">切换输入类型</button>
</div>
<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            type:'name',         
        },
        methods:{
            handleToggleClick:function (){
                this.type=this.type==='name'?'mail':'name';
            }
        }

    }
);

</script>
</body>
13、v-show

与v-if类似,但v-show本质是将dom元素的css属性设置为display:none
v-if是真正的条件渲染。v-show只是css属性的切换。

14、v-for列表渲染(循环)
  • 1、需要和in来结合使用,类似于 item in items的形式
<div id="app" >
    <ul>
    	<!--book是当前数组元素的别名-->
        <li v-for=" book in books">{{book.name}}</li>
    </ul>
</div>
<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            books:[
                {name:'<vue入门>'},
                {name:'<vue进阶>'},
                {name:'<vue高级>'}
            ],         
        }
    }
);

</script>
</body>
  • 2、列表渲染也支持使用of 来替代 in
<div id="app" >
    <ul>
        <li v-for=" book of books">{{book.name}}</li>
    </ul>
</div>
  • 3、v-for表达式支持一个可选参数作为当前项的索引
    这里使用index索引号
<div id="app" >
    <ul>
        <li v-for=" (book,index) of books">{{index}}--{{book.name}}</li>
    </ul>
</div>
  • 4、v-for也可以用在内置标签< template>上,将多个元素渲染
<body>  
<div id="app" >
    <ul>
        <template v-for=" book of books">
            <span >{{book.name}}</span>
            <span >{{book.author}}</span><br>
        </template>
    </ul>
</div>
<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            books:[
                {name:'<vue入门>',author:'zhangsna'},
                {name:'<vue进阶>',author:'lisi'},
                {name:'<vue高级>',author:'wanger'}
            ],         
        },
        methods:{
            handleToggleClick:function (){
                this.type=this.type==='name'?'mail':'name';
            }
        }

    }
);

</script>
</body>
  • 5、除了数组外,对象的属性也是可以遍历的
<body>  
<div id="app" >
     <span v-for=" book in books">{{book}}</span><br>

</div>
<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            books:{
                name:'<vue入门>',
                author:'zhangsna',
                price:30,
                
            }         
        }

    });

</script>
</body>
  • 6、遍历对象时,有两个参数可以选,一个是键名一个是索引,用括号括起来
    value,key,index必须按顺序来
    value:键值
    key:键名
    index:索引

  • 7、v-for可以迭代整数

<div id="app" >
    <ul>
     <li v-for=" n in 10">{{n}}</li><br>
    </ul>
</div>
15、数组更新

由于vue的核心是数据视图的双向绑定,当修改数组时,用v-for渲染的视图也会立即更新。
vue包含了一组观察数组变化的方法,使用这些方法改变数组也会触发视图更新

  • push():末尾添加元素
  • pop():删除并返回数组的最后一个元素
  • shift():把数组第一个元素删除并返回第一个元素的值
  • unshift():向数组开头添加一个或多个元素,并返回新的长度
  • splice():向数组添加/删除项目,然后返回被删除的项目
  • sort():排序数组
  • reverse():反转数组
    由于各个方法内部的不同,有的方法是直接改变数组,有的方法不会改变原数组(生成新数组),如:
    filter():过滤数组,并把符合条件的元素生成新的数组
    concat():连接两个或多个数组
    slice():字符串分割成字符串数组
    以下代码由于生成新数组,不会立刻得到更新
<body>  
<div id="app" >
    <ul>
     <li v-for=" book in books">{{book.bookname}}</li><br>
    </ul>
</div>
<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            books:[
                {bookname:"<vue实战>"},
                {bookname:"<vue实战进阶>"},
                {bookname:"<vue实战高级>"}
            ], 
        }
        

    });
app.books.push({booknname:"<vue宝典>"})

</script>
</body>
</html>

由于fliter()并不生成新数组,所以可以在页面中即时反馈出来

<body>  
<div id="app" >
    <ul>
     <li v-for=" book in books">{{book.bookname}}</li><br>
    </ul>
</div>
<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            books:[
                {bookname:"<vue实战>"},
                {bookname:"<JavaScript实战进阶>"},
                {bookname:"<vue实战高级>"}
            ], 
        }
        

    });
app.books=app.books.filter(function(item){//这里item指调用者的数组元素
    return item.bookname.match(/高级/);
});

</script>

</body>

vue观察到数组变化时,并不直接重新渲染整个列表,而是最大化复用dom元素,替换的数组中,含有相同元素的项不会被重新渲染,因此可以用新数组来替换数组,不需要考虑性能问题

以下情况的数组变化,vue是不能检测到的,因此也不会触发视图更新

  • 通过索引直接设置元素内容,如app.books[2]={…}
  • 修改数组长度,如:app.books.length=3

方法1、解决设置数组元素内容可以使用vue的set()方法

<body>  
<div id="app" >
    <ul>
     <li v-for=" book in books">{{book.bookname}}</li><br>
    </ul>
</div>
<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            books:[
                {bookname:"<vue实战>"},
                {bookname:"<JavaScript实战进阶>"},
                {bookname:"<vue实战高级>"}
            ], 
        }
        

    });

Vue.set(app.books,2,{
    bookname:"<node.js实战高级>"
});

</script>

</body>

方法2、webpack中使用组件化方法,使用$set方法

<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            books:[
                {bookname:"<vue实战>"},
                {bookname:"<JavaScript实战进阶>"},
                {bookname:"<vue实战高级>"}
            ], 
        }
        

    });

this.$set(app.books,2,{//this指的事当前组件实例,即app
    bookname:"<node.js实战高级>"
});
16、过滤与排序(通过计算属性)

当不想改变原数组,想通过一个数组的副本来做过滤或排序的显示时,可以使用计算属性来返回过滤或排序后的数组

<body>  
<div id="app" >
    <ul>
     <li v-for=" book in filterBooks">{{book.bookname}}</li><br>
    </ul>
</div>
<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            books:[
                {bookname:"<vue实战>"},
                {bookname:"<JavaScript实战进阶>"},
                {bookname:"<vue实战高级>"}
            ], 
        },
        computed:{
            filterBooks:function(){
                return this.books.filter(function(item){
                    return item.bookname.match(/实战进阶/);
                });
            }
        }

    });
</script>

</body>
</html>

还可以实现排序,以下是按书名长度排序

 computed:{
            filterBooks:function(){
                return this.books.filter(function(item){
                    return item.bookname.match(/实战进阶/);
                });
            },
            sortedBooks:function(){
                return this.books.sort(function(a,b){
                    return a.bookname.length<b.bookname.length;
                })
            }
        }
17、方法与事件的基本用法

使用v-on,类似于JavaScriptonclick的原生写法
也可以使用语法糖:@click
也可以使用方法名:写法为@事件=“方法名”

<body>  
<div id="app" >
    点击次数{{counter}}
    <button v-on:click="counter++">自增1</button>
    <button @click="counter++">自增1</button>
    <button @click="puls2">自增2</button>
    <button @click="pulsany(10)">自增10</button>
</div>
<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            counter:0
        },
        methods:{
            puls2:function(){
                this.counter+=2
            },
            pulsany:function(any){
                this.counter+=any
            },
        }

    });
</script>

</body>
</html>

vue提供了特殊变量$event,用于访问原生dom事件,如以下代码可以实现阻止连接打开

<body>  
<div id="app" >
   <a href="http://www.baidu.com" @click="handelClick('禁止打开',$event)">open link</a>
</div>
<script type="text/javascript">
var app=new Vue({
        el:"#app",
        data:{
            counter:0
        },
        methods:{
            handelClick:function(message,event){
                event.preventDefault();
                window.alert(message);
            }
        }
        

    });
</script>

</body>
18、修饰符

在@事件绑定的后面加小圆点“.”,再跟一个后缀来使用修饰符。用来达到上例中的event时间后要执行的操作,如event.preventDefault()
vue支持以下修饰符:
.stop
.prevent
.capture
.self
.once
如:

<div id="app" >
   <!--阻止单击事件冒泡-->
   <a href="http://www.baidu.com" @click.stop="handel">open link</a>
   <!--提交事件不再重载页面-->
   <form  @submit.prevent="handel"></form>
   <!--修饰符可以串联-->
   <a  @submit.stop.prevent="handel"></a>
   <!--只有修饰符-->
   <form  @submit.prevent></form>
   <!--添加事件侦听器时使用事件捕获模式-->
   <div  @click.captur='handle'>...</div>
   <!--只当时间再改元素本身(而不是子元素)触发时回调-->
   <div  @click.captur='handle'>...</div>
   <!--只触发一次,组件同样适用-->
   <div  @click.once='handle'>...</div>
   
</div>

在表单元素上监听键盘事件时,还可以使用按键修饰符

<div id="app" >
   <!--只有在keycode为13时调用vm.submit()-->
   <input  @keyup.13='submit'>...</div>
</div>

vue为按键提供了一系列快捷名称:
.enter
.tab
.delete
.esc
.space
.up
.down
.left
.right
这些按键修饰符也可以组合使用,或和鼠标一起配合使用
.ctrl
.alt
.shift
.meta(win下视窗键,mac下command键)

19、购物车小案例

实现商品列表,商品名称、单价,购买数量及操作等信息,实时显示总价,购买数量可以增加或减少,每类商品还可以从购物车中移除。
项目分离成三个文件
index.html
index.js
style.css

1、index.html

<!DOCTYPE html>
<html>
    <head>
    <link rel="stylesheet" type="text/css" href="style.css">
    </head>
<body>  
<div id="app" >
  <template v-if="list.length">
    <table class="myclass" border="1"  >
        <thead>
            <tr>
                <th></th>
                <th>商品名称</th>
                <th>商品单价</th>
                <th>购买数量</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            <tr v-for="(item,index) in list">
                <td>{{index+1}}</td>
                <td>{{item.name}}</td>
                <td>{{item.price}}</td>
                <td>
                    <button @click="handleReduce(index)" :disabled="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>

2、index.js

var app = new Vue({ 
    el: '#app',
    data: {
        list: [
            {
                id: 1,
                name: 'iphone 7',
                price: 6188,
                count:1
            },
            {
                id: 2,
                name: 'iPad Pro',
                price: 5888,
                count:1
            },
            {
                id: 3,
                name: 'MacBook Pro',
                price: 21488,
                count:1
            }
        ]

    },
    computed: {
        totalPrice: function () {
            var total = 0;
            for (var i = 0; i < this.list.length; i++) { 
                var item = this.list[i];
                total += item.price * item.count;
            }
            return total.toString().replace(/\B(?=(\d{3})+$)/g, ',');
        }
    },
    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)
        },
    }
});

3、style.css

.myclass{border-collapse: collapse; width: 500px; }
.myclass tr td{border:1px solid black; text-align: center;}

4、最终效果:
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值