Vue.js学习笔记(第二弹)

本章目录

1.计算属性setter和getter

2.计算属性和methods的对比

         3.块级作用域-let和var

4.三种方案对比-ES5没有闭包-有闭包-ES6的let

5.const的使用和注意点

6.ES6对象字面量增强写法

8.v-on的基本使用和语法糖

9.v-on的参数传递问题

10.v-on的修饰符使用

11.v-if和v-else-if和v-else的使用

12.登录切换的小案例

13.登录切换的input复用问题

14.v-show的使用以及和v-if的区别

15.v-for遍历数组和对象

16.v-for-绑定和非绑定key的区别

17.数组中哪些方法是响应式的

18.作业的回顾和实现

19-22.购物车案例-(界面搭建、过滤器的使用、改变购买数量、移除按钮-最终价格)


1.计算属性setter和getter

computed属性默认是下面是这样的,但是它是有Get 和 Set属性的

<script>
	const app = new Vue({
		el:'#app',
		data:{
			FirstName:'AA',
			lastName:'BB'
		},
		computed:{
			fullName:function(){
				return this.FirstName + ' '+ this.lastName; 
			}
		}
	})
</script>

get和set属性

<div id="app">
	<h4>{{fullName}}</h4>
</div>
<script>
	const app = new Vue({
		el:'#app',
		data:{
			FirstName:'AA',
			lastName:'BB',
		},
		computed:{
			// fullName:function(){
			// 	return this.FirstName + ' '+ this.lastName; 
			// }
			fullName:{
				set:function(newValue){
					console.log('---',newValue);
					const name = newValue.split(' ');//空格切割字符串
					this.FirstName = name[0];
					this.lastName = name[1];
				},
				get:function(){
					return this.FirstName + ' '+ this.lastName; 
				}
			}
		}
	})
</script>

2.计算属性和methods的对比

页面同时调用多次方法和计算,方法会调用多次,计算只会调用一次,性能更高

主要原因是因为计算内部有缓存,会把刚才的操作缓存下来,而方法不会,只会重复调用,影响性能

<div id="app">
	{{full()}}
	{{full()}}
	{{full()}}
	{{full()}}
	{{full()}}
	{{fullName}}
	{{fullName}}
	{{fullName}}
	{{fullName}}
	{{fullName}}
</div>
<script>
	const app = new Vue({
		el:'#app',
		data:{
			firstName:'qixiannv',
			lastName:'dongyong',
		},
		methods:{
			full:function(){
				console.log('full');
				return this.firstName;
			}
		},
		computed:{
			fullName:function(){
				console.log('fullName');
				return this.lastName;
			}
		}
	})
</script>

3.块级作用域-let和var

let:可变变量 (块级作用域:{}变量在什么范围内可用)   const:不可变变量

var:全局变量

没有块级作用域引发的问题

(1)if的块级(var变量没有块级作用域,定义在局部的变量被外面同名的变量更改了)

	//1.没有块级作用域引发的问题:if的块级
	var func;
	if(true)
	{
		var name = 'why';
		func = function(){
			console.log(name);
		}
	}
	name = 'lyf';
	func();
	console.log(name);

(2)for的块级

<button type="button">按钮</button>
<button type="button">按钮</button>
<button type="button">按钮</button>
<button type="button">按钮</button>
<button type="button">按钮</button>

var btn = document.getElementsByTagName('button');
    for(var i =0;i<btn.length;i++)
    {
        console.log('第'+ i +'个按钮被点击');
    }

闭包:函数是一个作用域,i在其中,不会被别的改掉

var btn = document.getElementsByTagName('button');
for(var i =0;i<btn.length;i++)
{
    (function(i){
        btn[i].addEventListener('click',function(){
	console.log('第'+ i +'个按钮被点击');
    })
    })(i)
}
var name ='aa';
function abc(name){
    console.log(name);//输出的是abc,优先输出自己作用域的内容
}
abc('123');
var name ='bbb';

(3)用let执行 let有块级作用域

4.三种方案对比-ES5没有闭包-有闭包-ES6的let

es5没有块级作用域,采用闭包的方法可以避免变量污染,而es6中有块级变量域,很好的解决了这个问题

var btn = document.getElementsByTagName('button');
for(var i =0;i<btn.length;i++)
{
    console.log('第'+ i +'个按钮被点击');
}

es5的闭包(没有作用域,i会泄露为全局变量,有作用域,互不干扰)

var btn = document.getElementsByTagName('button');
     for(var i =0;i<btn.length;i++)
       {
	 (function(i){
	  btn[i].addEventListener('click',function(){
	  console.log('第'+ i +'个按钮被点击');
	  })
	 )(i)//作用域中又属于自己的i,不被外面的i影响
       }

(3)用let执行 let有块级作用域

(4)es6中有块级作用域了,不用像es5那样需要闭包了

5.const的使用和注意点

使用const修饰的标识符为常量,不可以再次赋值

(1)赋值之后,不可修改

<script>
//注意1:一旦给const修饰的标识符被赋值之后,不能修改
const name ='aa';
name ='nn';
</script>

(2)定义const常量后必须赋值

<script>
// 注意2:在使用const定义标识符,必须进行赋值
// const name;
</script>

(3)指向对象不可修改,可以改变对象内部属性

<script>
// 注意3:常量的含义是指向的对象不能修改,但是可以改变内部的属性
const obj = {
	name:'lyf',
	age:5,
	color:'pink',
	func:function(){
		console.log('walyf');
	}
}
console.log(obj);
obj.name='hg';
obj.age = 18;
obj.color = 'green';
obj.func();
console.log(obj);
</script>

const内存地址不可修改

eg:(括号内为变量的内存地址)

const (#x01)  obj(#x01)

再次修改(#x02)  obj(#x02),则会报错,const内存地址不可修改

但是如果改变内部属性是可以的,因为没有改变到const变量的内部地址

const (#x01)  obj(#x01)-> name   (name为obj对象的内部属性)

6.ES6对象字面量增强写法

const obj = new object();

简写:const obj = {} ({} 大括号表示对象字面量)

	// const obj = new object();
	const obj = {
		name :'lyf',
		age:18,
		run:function(){
			console.log('lyf run');
		},
		eat:function(){
			console.log('lyf eat');
		},
	}
	obj.run();obj.eat();

es5和es6的写法(es6为增强写法)

(1)属性的增强写法

const name = 'lyf';
const age = 18;
//1.es5写法
// const obj = {
// 	name:name,
// 	age:age,
// }
//2.es6写法
const obj = {
	name,
	age,//直接写对象名,就直接把同名的变量名赋进去
}
console.log(obj);
console.log(obj.age);

(2)方法的增强写法

//2.方法的增强写法
//(1)es5写法
const obj = {
	func:function(){
		console.log('walyf');
	}
}
//(2)es6写法
const obj = {
	func(){
		console.log('wyahg');
	}
}
obj.func();

(3)javascript没有类型推测

8.v-on的基本使用和语法糖

(1)点击进行加减计算

<div id="app">
	<h1 :style="{color:'#c00'}">{{computer}}</h1>
	<!-- <button v-on:click="computer++">+</button>
	<button v-on:click="computer--">-</button> -->
	<button v-on:click="getCom">+</button>
	<button v-on:click="deCom">-</button>
</div>
<script>
	const app = new Vue({
		el:'#app',
		data:{
			computer: 0
		},
		methods:{
			getCom(){
				this.computer++;
			},
			deCom(){
				if(this.computer>1)
				{
					this.computer--;
				}
			}
		}
	})
</script>

(2)语法糖 :v-on:click @click

9.v-on的参数传递问题

(1)没有参数的情况下,()括号可以省略

(2)如果函数需要参数,但没有传入,那么函数的形参为undefined

如果函数不需要传入参数,那么括号()可以省略

如果是js的话,方法中需要参数,没有传入也会报undefined错误

eg:function abc(name) {}    abc(); ~~~ undefined

<div id="app">
	<button @click="btnClick">按钮1</button><!--如果函数不需要传入参数,那么括号()可以省略-->
	<!--在事件定义时,写函数时忽略了小括号,但是方法本身是需要一个参数的,这个时候如果没有传参数进去会报undefined错误-->
	<button @click="btnClick2">按钮2</button><!--错误--> 
	<button @click="btnClick2('hg')">按钮2</button><!--正确-->
</div>
<script>
	const app = new Vue({
		el:'#app',
		data:{
			computer: 0
		},
		methods:{
			btnClick(){
				console.log('walyf666');
			},
			btnClick2(h){
				console.log('wa'+h+'666');
			}
		}
	})
</script>

(3)在事件定义时,写方法时省略了小括号,但方法本身是需要一个参数的,这个时候Vue会默认将浏览器生成的event对象作为参数传入方法中

<div @click="onclick">按钮</div>
methods:{
	onclick(event){
	alert(event);//event中有对象参数
	}
}

(4)需要event参数,也需要其他参数

<!--方法定义时,我们需要event对象,同时又需要其他参数-->
<!--在调用方法,如何手动的获取到浏览器参数的event对象:$event-->
<div @click="btn3('123',$event)">按我</div>
btn3(abc,event){
    alert(abc);
    alert(event);
}

10.v-on的修饰符使用

(1)@click.stop

事件冒泡:事件冒泡的走向是由父节点向子节点去触发同名事件

<div id="app">
	<!--事件冒泡:事件冒泡的走向是由父节点向子节点去触发同名事件-->
	<button @click="btnClick">
		<!-- <div @click="divClick">按我</div> -->
                <!--@click.stop阻止事件冒泡-->
		<div @click.stop="divClick">按我</div>
	</button>
</div>
<script>
	const app = new Vue({
		el:'#app',
		data:{

		},
		methods:{
			btnClick(){
				console.log("aa");
			},
			divClick(){
				console.log("bb");	
			}
		}
	})
</script>

(2)@click.prevent(阻止服务器自动提交)自己定义提交方式,点击自动提交

<div id="app">
	<form action="?">
		<input type="submit" value="提交" @click.prevent="submitBtn">
	</form>
</div>
<script>
	const app = new Vue({
		el:'#app',
		data:{

		},
		methods:{
			submitBtn(){
				console.log('sub');
			}
		}
	})
</script>

(3)@keyup监听键盘某个按钮的点击

<div id="app">
    <input type="text" @keyup.enter="keyups"/><!--回车-->
</div>
<script>
	const app = new Vue({
		el:'#app',
		data:{

		},
		methods:{
			keyups(){
			    console.log('hgg');
			}
		}
	})
</script>

(4)@click:once:方法只调用一次

<div id="app">
    <button @click.once="btnSubmit">按钮</button>
</div>
<script>
	const app = new Vue({
		el:'#app',
		methods:{
			btnSubmit(){
			    console.log('lyff');
			}
		}
	})
</script>

11.v-if和v-else-if和v-else的使用

(1)v-if和v-else

<div id="app">
	<!--为true时显示div内容-->
	<!--1.-->
	<div v-if="false">
		{{message}}
	</div>
	<!--2.-->
	<div v-if="isshow">
		{{message}}
	</div>
	<div v-else>
		isshow为false显示我
	</div>
</div>
<script>
	const app = new Vue({
		el:'#app',
		data:{
			message:'lyfihg',
			isshow:false,
		},
		methods:{

		}
	})
</script>

(2)v-else -if(复杂时,用compted计算属性) v-else -if与compted对比

<div id="app">
	<div v-if="score>=90">优秀</div>
	<div v-else-if="score>=80">良好</div>
	<div v-else-if="score>=60">及格</div>
	<div v-else>不及格,仍需努力!</div>
</div>
<script>
	const app = new Vue({
		el:'#app',
		data:{
			score:95,
		}
	})
</script>
<div id="app">
	<div v-if="score>=90">优秀</div>
	<div v-else-if="score>=80">良好</div>
	<div v-else-if="score>=60">及格</div>
	<div v-else>不及格,仍需努力!</div>
	<div>{{sum}}</div>
</div>
<script>
	const app = new Vue({
		el:'#app',
		data:{
			message:'lyfihg',
			isshow:false,
			score:92,
		},
		computed:{
			sum(){
				let msg = "";
				if(this.score>=90)
				{
				    msg = "优秀";
				}
				else if(this.score>=80)
				{
				    msg = "良好";
				}
				else if(this.score>=60)
				{
				    msg = "及格";
				}
				else{
				    msg = "不及格,仍需努力!";
				}
				return msg;
			}
		}
	})
</script>

12.登录切换的小案例

<div id="app">
	<span v-if="ischeck">
		<label for="username">用户账号</label>
		<input id="username" key="username"
		><!--label的for和input的id名称相同,点击labelinput的文本框会聚焦-->
	</span>
	<span v-else>
		<label for="userEmail">用户邮箱</label>
		<input id="userEmail"  key="userEmail">
	</span>
	<input value="点击切换" @click="ischeck=!ischeck" type="button">
</div>
<script>
	const app = new Vue({
		el:'#app',
		data:{
			ischeck:true,
		},
		methods:{

		}
	})
</script>

13.登录切换的input复用问题

Vue进行Dom渲染时,出于性能考虑,会尽可能复用存在的元素

复用解决:在标签中加一个key属性,表明这是唯一元素

<span v-if="ischeck">
		<label for="username">用户账号</label>
		<input id="username" key="username"/>
	</span>
	<span v-else>
		<label for="userEmail">用户邮箱</label>
		<input id="userEmail"  key="userEmail"/>
	</span>

14.v-show的使用以及和v-if的区别

切换频率高:v-show

只有一次切换:v-if

<div id="app">
	<!--v-if:当条件为false时,包含v-if指令的元素,根本不会存在dom中(元素被删除)-->
	<div v-if="isshow" id="aa">{{message}}</div>
	<!--v-show:当条件为false时,v-show只是给我们的元素添加一个行内样式:display:none;-->
	<div v-show="isshow" id="bb">{{message}}</div>
</div>
<script>
	const app = new Vue({
		el:'#app',
		data:{
			message:'who is me?',
			isshow:false,
		}
	})
</script>

15.v-for遍历数组和对象

(1)遍历数组

<div id="app">
	<!--1.在遍历的过程中,没有使用索引值(下标值)-->
	<ul>
	    <li v-for="item in name">{{item}}</li>
	</ul>
	<!--2.在遍历的过程中,获取索引值(下标值)-->
	<ul>
	    <li v-for="(item,index) in name">{{index}}~~~{{item}}</li>
	</ul>
</div>
<script>
	const app = new Vue({
		el:'#app',
		data:{
			name:['who','is','me','zjh'],
		}
	})
</script>

(2)遍历对象

<div id="app">
    <!--遍历对象-->
    <ul>
	<li v-for="item in info">{{item}}</li><!--一个输出的是值(value)-->
    </ul>
    <ul>
        <li v-for="(value,key) in info">{{key}}~~{{value}}</li>
	<!--两个输出的是值,键(value,key)-->
    </ul>
    <ul>
	<li v-for="(value,key,index) in info">{{index}}~~{{key}}~~{{value}}</li>
		<!--三个输出的是值,键,索引(value,key,index)-->
    </ul>
</div>
<script>
	const app = new Vue({
		el:'#app',
		data:{
			name:['who','is','me','zjh'],
			info:{
				name:'lyf',
				age:'18',
				Love:'hg',
				sex:'girl',
			}
		}
	})
</script>

16.v-for-绑定和非绑定key的区别

首先,它们区别主要在于 虚拟DOM的复用,绑定key可以更好的复用(遍历用key标识速度会提升)

没有绑定key:在插入的数据之后的数据全部会被更新

绑定key:原本的数据key不变,只是挪用了一下位置,把现在要操作的数据插入进去

假如我们有一个数组 arr = [1,2,3,4],我们要在2后面插入一个值9;

如果绑定了key值,那么会是这样的情况:

如果没有绑定key值,那么会是这样的情况: 

17.数组中哪些方法是响应式的

1.push()方法(追加到元素最后)

//1.push方法
this.latter.push('1','2');
//2.通过索引值修改数组中的元素
this.latter[0]="aaa";
console.log(this.latter);

2.pop():删除数组中最后一个元素

this.latter.pop();

3.shift():删除数组中第一个元素

this.latter.shift();

4.unshift():在数组最前面添加元素

this.latter.unshift('aa');

5.splice():删除元素/插入元素/替换元素

// (1)删除元素:第二个元素传入你要删除几个元素(如果没有传,就删除后面所有的元素)
this.latter.splice(1,1);//删除第一个后面的值
 this.latter.splice(1);//只传入一个,表示删除第一个后面的所有值
// (2)替换元素:第二个参数,表示我们替换几个元素,后面是用于替换前面的元素
 this.latter.splice(1,3,'m','n','l','x');
// (3)插入元素:第二个参数,传入0,并且后面跟上要插入的元素
 this.latter.splice(1,0,'m','n','l','x');

6.sort():排序

this.latter.sort();

7.reverse()反转

this.latter.reverse();
// 注意:通过索引值修改数组中的元素(不是响应式)
// (1)this.latter[0]="asda";(不是响应式)
// (2)this.latter.splice(0,1,'ccc');通过替换(响应式)

8.set(要修改的对象,索引值,修改后的值)

Vue.set(this,latter,0,'eeeee');

18.作业的回顾和实现

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script src="../vue.js"></script>
<title></title>
<style>
	.red{color:#c00;}
</style>
</head>

<body>
<div id="app">
	<ul>
		<li v-for="(item,index) in movers" @click="onclick(index)" :class={red:active===index}>
			{{index}}-{{item}}
		</li>
	</ul>
</div>
<script>
	const app = new Vue({
		el:'#app',
		data:{
			movers:['还珠格格','放羊的星星','天国的嫁衣'],
			active :0,
		},
		methods:{
			onclick(index){
				this.active = index;
			}
		}
	})
</script>
</body>
</html>

19-22.购物车案例-(界面搭建、过滤器的使用、改变购买数量、移除按钮-最终价格)

(1)价格保留两位小数:{{item.price.toFixed(2)}}

(2)价格前加¥符号

1.价格前加¥符号:{{'¥'+item.price.toFixed(2)}}

1.方法中传参,加¥:{{getPrice(item.price)}}

methods:{
        getPrice(price){
            return '¥'+price.toFixed(2);
        }
    },

2.过滤器: {{item.price|getPrice}}

    filters:{//过滤器
        getPrice(price){
            return '¥'+price.toFixed(2);
        }
    }

购物车代码如下:

html:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script src="../vue.js"></script>
<title></title>
</head>

<body>
<div id="app">
<div v-if="books.length">
	<table>
		<thead>
			<tr>
				<th><th>
				<th>书籍名称<th>
				<th>出版日期<th>
				<th>价格<th>
				<th>购买数量<th>
				<th>操作<th>
			</tr>
		</thead>
	</table>
	<table>
		<tr v-for="(item,index) in books">
			<td>{{item.id}}</td>
			<td>{{item.name}}</td>
			<td>{{item.date}}</td>
			<!-- <td>{{getPrice(item.price)}}</td> -->
			<td>{{item.price|getPrice}}</td>
			<td>
			<!-- <button @click="decrement(index)" v-bind:disabled="item.count<=1">-</button> -->
			<button @click="decrement(index)" :disabled="item.count<=1">-</button>
			{{item.count}}
			<button @click="increment(index)">+</button>
			</td>
			<td><button @click="removeHandle(index)">移除</button></td>
		</tr>
	</table>
	<h2>总价:{{totalPrice|getPrice}}</h2>
</div>
<h2 v-else>购物车没有东西</h2>
</div>
<script src="min.js"></script>
</body>
</html>

js:

const app= new Vue({
	el:'#app',
	data:{
		books:[
			{
				id:1,
				name:'还珠格格',
				date:'1998.01.30',
				price:89.23,
				count:1
			},
			{
				id:2,
				name:'放羊的星星',
				date:'2007.01.30',
				price:89.00,
				count:1
			},
			{
				id:3,
				name:'命中注定我爱你',
				date:'2010.01.30',
				price:89.00,
				count:1
			},
				{
				id:4,
				name:'海派甜心',
				date:'2009.01.30',
				price:89.00,
				count:1
			},
		]
	},
	methods:{
		getPrice(price){
			return '¥'+price.toFixed(2);
		},
		increment(index){
			this.books[index].count++;
		},
		decrement(index){
			this.books[index].count--;
		},
		removeHandle(index)
		{
			this.books.splice(index,1);
		}
	},
	filters:{//过滤器
		getPrice(price){
			return '¥'+price.toFixed(2);
		}
	},
	computed:{
		totalPrice(){
			let totalPrice = 0;
			for(let i=0;i<this.books.length;i++)
			{
				totalPrice += this.books[i].price*this.books[i].count;
			}
			return totalPrice;
		}
	}
})

2020.4.20-2020.5.3这章节学习的时间跨度有点长啊,还是要继续加油,在学习的过程中越发觉得Vue有魅力,加油

ヾ(◍°∇°◍)ノ゙

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值