Vue.js(二)

v-on

1. 介绍
  • 作用:绑定事件监听器
  • 缩写:@
  • 预期:Function | Inline Statement | Object
  • 参数: event
2. 参数传递
  • 如果该方法不需要额外参数,那么方法后的 () 可以不添加。 如果方法本身有一个或多个参数,那么会默认将原生事件 event 参数传递给第一个参数
  • 如果需要同时传入某个参数,同时需要 event 时,可以通过 $event 传入事件
3. 修饰符
  • .stop:调用 event.stopPropagation(),阻止冒泡
  • .prevent:调用 event.preventDefault(),阻止默认行为
  • .[keyCode | keyAlias]:只有当事件从特定键触发时才触发回调
  • .native:监听组件根元素的原生事件
  • .once:只触发一次回调
<!--1. .stop的使用,btn的click事件不会传播,不会冒泡到上层,调用event.stopPropagation() -->
<div @click="divClick">
	<button @click.stop="btnClick">按钮1</button>
</div>
<!-- 2. .prevent 调用event.preeventDefault阻止默认行为  -->
<form action="www.baidu.com">
	<button type="submit" @click.prevent="submitClick">提交</button>
</form>
<!--3. 监听键盘的事件 -->
<input type="text" @click.enter="keyup">

v-if、v-else、v-if-else

  • v-if 的条件为 false 时,对应的元素以及其子元素不会渲染,也就是不会有对应的标签出现在 DOM 中
1. 切换小案例
<div id="app">
	<span v-if="isPhone">
    	<label for="phone">用户电话:</label>
    	<input type="text" id="phone" placeholder="请输入电话号">
    </span>
    <span v-else>
    	<label for="email">用户邮箱:</label>
      	<input type="text" id="email" placeholder="请输入邮件" >
    </span>
    <button @click="btnClick()">切换类型</button>
</div>

在这里插入图片描述

问题 切换后,输入框中的内容没有消失

在这里插入图片描述

解决方法 key
  • key 是各不相同的
<div id="app">
    <span v-if="isPhone">
		<label for="phone">用户电话:</label>
      	<input type="text" id="phone" placeholder="请输入电话号" key="phone">
    </span>
    <span v-else>
    	<label for="email">用户邮箱:</label>
    	<input type="text" id="email" placeholder="请输入邮件" key="email">
    </span>
    <button @click="btnClick()">切换类型</button>
</div>

在这里插入图片描述

2. v-show 和 v-if 的区别
  • v-if 条件为 false 时,不会有对应的元素存在于 DOM 中
  • v-show 条件为 false 时,仅仅是将元素的 display 属性置为 none
  • 选择:
    1. 当需要在显示与隐藏之间频繁切换时,使用 v-show
    2. 当只有一次切换时,使用 v-if

v-for 遍历数组和对象

1. 遍历数组
<div id="app">
	<!-- 1.遍历过程没有使用索引(下标值) -->
    <ul>
    	<li v-for="item in names" >{{item}}</li>
    </ul>
    <!-- 2.遍历过程有使用索引(下标值) -->
    <ul>
        <li v-for="(item,index) in names"  >{{index+":"+item}}</li>
    </ul>
</div>
2. 遍历对象
<div id="app">
	<!-- 1. 遍历 value -->
    <ul>
    	<li v-for="value in user" >{{value}}</li>
    </ul>
    <!-- 2. value-key -->
    <ul>
    	<li v-for="(value,key) in user" >{{key+"-"+value}}</li>
    </ul>
    <!-- 3. value-key-index -->
    <ul>
    	<li v-for="(value,key,index) in user" >{{key+"-"+value+"-"+index}}</li>
    </ul>
</div>
3. key 属性

官方推荐:使用 v-for 时,给对应的元素或组件加上一个 :key 属性

  • key 的作用主要是为了高效的更新虚拟 DOM
  • 不加key渲染时候会依次替换渲染,加了key会直接将其放在指定位置,加key提升效率
<body>
  	<div id="app">
    	<!-- 不加key如果要插入f,要依次改变插入位置之后的所有元素 -->
    	<ul>
      		<li v-for="item in letters">{{item}}</li>
    	</ul>
    	<button @click="add1">没有key</button>
    	<!-- 加key,如果要插入f,使用diff算法高效,index会一直变,所以item如果唯一可以使用item-->
    	<ul>
        	<li v-for="item in letters" :key="item">{{item}}</li>
    	</ul>
    	<button @click="add2">有key</button>
  	</div>
  	<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  	<script>
    	const app = new Vue({
      		el:"#app",
      		data:{
        		letters:['a','b','c','d','e']
      		},
      		methods: {
        		add1(){
          			this.letters.splice(2,0,'f')
       			},
        		add2(){
          			this.letters.splice(2,0,'f')
        		}
      		}
    	})
  	</script>
</body>
4. 数组的响应式方法
<body>
  	<div id="app">
    	<ul>
      		<li v-for="item in letters">{{item}}</li>
    	</ul>
    	<button @click="btn1">push</button><br>
    	<button @click="btn2">通过索引值修改数组</button>
  	</div>
  	<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  	<script>
    	const app = new Vue({
      		el:"#app",
      		data:{
        		letters:['a','b','c','d','e']
      		},
      		methods: {
        		btn1(){
          			//1.push
          			this.letters.push('f');
          			//2.pop()删除最后一个元素
          			//this.letters.pop();
          			//3.shift()删除第一个
          			//this.letters.shift();
          			//4.unshift()添加在最前面,可以添加多个
          			//this.letters.unshift('aaa','bbb','ccc');
          			//5.splice():删除元素/插入元素/替换元素
          			// this.letters.splice(2,0,'aaa');
          			//6.sort()排序可以传入一个函数
          			//this.letters.sort();
          			//7.reverse()反转
          			// this.letters.reverse();
        		},
        		btn2(){
          			this.letters[0]='f';
        		}
      		}
    	})
  	</script>
</body>
  • 通过索引值修改数组的值,这种情况不是响应式的

  • 通过数组的方法,例如 push()pop()shift()unshift()splice()sort()reverse() 等方法修改数组的数据,DOM元素会随之修改

  • splic() :删除元素、插入元素、替换元素

    splice(1,1):在索引为1的地方删除一个元素,第二个元素不传,直接删除后面所有元素
    splice(index,0,'aaa'):在索引 index 后面删除0个元素,加上’aaa’
    splice(1,1,'aaa'):替换索引为 1 的后一个元素为’aaa’

购物车小demo

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
  	<meta charset="UTF-8">
  	<meta name="viewport" content="width=device-width, initial-scale=1.0">
  	<title>Day01</title>
  	<style>
    	#shopping-cart {
      		margin: 100px;
    	}
    	table {
			width: 600px;
      		border: 1px;
      		border-collapse: collapse;
      		border-spacing: 0;
      		box-shadow: 3px 3px 10px #aaaaaa;
    	}
    	th,
    	td {
      		padding: 8px 16px;
      		border: 1px solid #e9e9e9;
      		text-align: left;
    	}
    	th {
      		background-color: #f7f7f7;
      		color: #5c6b77;
      		font-weight: 600;
    	}
  	</style>
</head>

<body>
  	<div id="shopping-cart">
    	<table>
      		<thead>
        		<tr>
          			<th>书籍名称</th>
          			<th>出版日期</th>
          			<th>价格</th>
          			<th>购买数量</th>
          			<th>操作</th>
        		</tr>
      		</thead>
      		<tbody>
        		<tr v-for="(item,index) in books" :key="index">
          			<td>{{item.name}}</td>
	          		<td>{{item.beginDate}}</td>
          			<td>{{item.price | formatPrice}}</td>
          			<td><button @click="decrease(index)" :disabled="item.count<=0">-</button>{{item.count}}<button @click="increase(index)">+</button></td>
          			<td><button @click="remove(index)">移除</button></td>
        		</tr>
      		</tbody>
    	</table>
    	<h3>总价格为:{{sum | formatPrice}}</h3>
  	</div>
	<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  	<script>
    	const app = new Vue({
      		el: "#shopping-cart",
      		data: {
        		books: [{
            			name: "《算法导论》",
            			beginDate: "2006-9",
            			price: 85.00,
            			count: 1
          			},
          			{
            			name: "《UNIX编程艺术》",
            			beginDate: "2006-2",
            			price: 59.00,
            			count: 1
          			},
          			{
            			name: "《编程大全》",
            			beginDate: "2008-10",
            			price: 39.00,
            			count: 1
          			},
          			{
            			name: "《代码大全》",
            			beginDate: "2006-3",
            			price: 128.00,
            			count: 1
          			}],
	      		},
      			methods: {
        			increase(index) {
          				return this.books[index].count++;
        			},
        			decrease(index) {
          				return this.books[index].count > 0 ? this.books[index].count-- : false;
        			},
        			remove(index) {
          				return this.books.splice(index, 1);
        			},
      			},
      			computed: {
        			sum() {
						let totalPrice = 0;
        				// 1. 普通for循环
          				// for (let i = 0; i < this.books.length; i++) {
            			//     totalPrice += this.books[i].price * this.books[i].count;
	          			//  }
          				// 2.增强for循环
        				// for (let i in this.books) {
	        			//     totalPrice = totalPrice + this.books[i].price * this.books[i].count;
        				// }
        				// 3.for of
        				// for (const book of this.books) {
        				//     totalPrice = totalPrice + book.price * book.count;
	        			// }
          				// return totalPrice;
	          			// 4. 使用高阶函数
        				// return this.books.map(function (book) {
        				//     return book.price * book.count;
	        			// }).reduce(function (preValue,currentValue) {
        				//     return preValue + currentValue;
        				// })
        				// 5. 高阶函数简写(箭头函数)
        				return this.books.length === 0 ? 0 : this.books.map(book => book.price * book.count).reduce((preValue,currentVlue) => preValue + currentVlue);
      				}
        		}
      		},
      		filters: { //过滤器
        		formatPrice(price) {
          			return "¥" + price.toFixed(2);
        		}
      		}
   		})
  	</script>
</body>
</html>
3. 函数解析
  • filter过滤函数
const nums = [2,3,5,1,77,55,100,200];
// 要求: 获取nums中大于50的数
// 回调函数会遍历nums中每一个数,传入回调函数,在回调函数中写判断逻辑,返回true则会被数组接收,false会被拒绝
let newNums = nums.filter(function (num) {
  	if(num > 50){
    	return true;
  	}
 	return false;
})
// 可以使用箭头函数简写
// let newNums = nums.filter(num => num >50)
  • map 高阶函数
// 要求: 将已经过滤的新数组每项乘以2
// map函数同样会遍历数组每一项,传入回调函数为参数,num是map遍历的每一项,回调函数function返回值会被添加到新数组中
let newNums2 = newNums.map(function (num) {
  	return num * 2;
})
// 简写
// let newNums2 = newNums.map(num => num * 2)
  • reduce 高阶函数
// 要求: 将newNums2的数组所有数累加
// reduce函数同样会遍历数组每一项,传入回调函数和‘0’为参数,0表示回调函数中preValue初始值为0,回调函数中参数preValue是每一次回调函数function返回的值,currentValue是当前值
// 例如数组为[154, 110, 200, 400],则回调函数第一次返回值为0+154=154,第二次preValue为154,返回值为154+110=264,以此类推直到遍历完成
let newNum = newNums2.reduce(function (preValue,currentValue) {
  	return preValue + currentValue;
},0)
//简写
// let newNum = newNums2.reduce((preValue,currentValue) => preValue + currentValue)
// 三个需求综合
let n = nums.filter(num => num > 50).map(num => num * 2).reduce((preValue,currentValue) => preValue + currentValue);

v-model

  • 实现表单元素和数据的双向绑定
1. 绑定 input
<input type="text" v-model="message">
<h2>{{message}}</h2>
2. v-bind 和 v-on 实现 v-model
<input type="text" :value="message2" @input="message2 = $event.target.value">
<h2>{{message2}}</h2>
3. v-model 结合 radio
  • radio单选框的 name 属性是互斥的,如果使用 v-model,可以不使用 name 就可以互斥
<div id="app">
	<label for="male">
    	<input type="radio" id="male" name="sex" value="" v-model="sex"></label>
    <label for="female">
        <input type="radio" id="female" name="sex" value="" v-model="sex"></label>
	<div>你选择的性别是:{{sex}}</div>
</div>
4. v-model 结合 checkbox
  • 单选框
<label for="agree">
	<input type="checkbox" id="agree" v-model="isAgree">同意协议
</label>
<h2>isAgree:{{isAgree}}</h2>
<button :disabled="!isAgree">下一步</button>

在这里插入图片描述

  • 复选框
<input type="checkbox" value="A" v-model="letter">A
<input type="checkbox" value="B" v-model="letter">B
<input type="checkbox" value="C" v-model="letter">C
<input type="checkbox" value="D" v-model="letter">D
<input type="checkbox" value="E" v-model="letter">E
<h2>{{letter}}</h2>

在这里插入图片描述

5. v-model 结合 select
<select name="" id="fruit" v-model="fruit">
	<option value="apple">apple</option>
    <option value="banana">banana</option>
    <option value="orange">orange</option>
    <option value="grape">grape</option>
    <option value="peach">peach</option>
</select>
<h2>fruit:{{fruit}}</h2>

<select name="" id="fruits" v-model="fruits" multiple>
	<option value="apple">apple</option>
    <option value="banana">banana</option>
    <option value="orange">orange</option>
    <option value="grape">grape</option>
    <option value="peach">peach</option>
</select>
<h2>fruits:{{fruits}}</h2>

在这里插入图片描述

6. 值绑定
  • 动态给 value 赋值
<label :for="item" v-for="item in sports">
	<input type="checkbox" :value="item" :id="item" v-model="selectedSports">{{item}}
</label>
<h4>selectedSports:{{selectedSports}}</h4>
const app = new Vue({
	el: "#app",
    data: {
    	selectedSports: [],
      	sports: ['篮球', '台球', '足球', '羽毛球', '高尔夫球', '排球', '跳高', '跳远', '自行车', '滑冰', '滑雪'],
    }
})

在这里插入图片描述

7. 修饰符
  • .lazy:让数据在失去焦点或者回车时才会更新
  • .number:v-model 默认情况下,输入框中的内容都是字符串类型,.number 修饰符可以让输入框中输入的内容自动转换为数字类型
  • .trim:过滤内容两端的空格
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值