基础语法(2)
# 条件渲染
指令 | 释义 |
---|---|
v-if | 相当于 if |
v-else-if | 相当于 else if |
v-else | 相当于 else |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
<style></style>
</head>
<body>
<div id="app" style="margin: 20px">
<h3>案例:if、else if、else</h3>
<h2 v-if="score>90">优秀</h2>
<h2 v-else-if="score>80 && score<=90">良好</h2>
<h2 v-else-if="score>=60 && score<=80">及格</h2>
<h2 v-else>不及格</h2>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
score: 70,
},
methods: {}
})
</script>
</html>
<!-- 可以在浏览器的Console改巴改巴,观察双向绑定的结果 vm.score = 33-->
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 列表渲染
# 商品显示
v-if+v-for+v-else控制购物车商品的显示
<!--
伪代码: `<标签 v-for="i in 变量">{{i}} {{变量}}</标签>`
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
<style>
table, td {
border: 1px solid black;
text-align: center;
}
</style>
</head>
<body>
<div id="app" style="margin: 20px">
<h2>我的购物车</h2>l
<button @click="refresh" v-show="isShow">点击刷新购物车</button>
<br><br>
<table v-if="!shopping_car.length==0">
<tr>
<td>商品名称</td>
<td>价格</td>
</tr>
<!-- 每次都从shopping_car数组中拿出一个对象 -->
<!-- 在Vue2中v-for得优先级是高于v-if的,若同时使用,那么每次渲染都会先循环再进行条件判断造成性能的浪费 -->
<tr v-for="item in shopping_car">
<td>{{item.name}}</td>
<td>{{item.price}}</td>
</tr>
</table>
<table v-else>
<tr>
<td>商品名称</td>
<td>价格</td>
</tr>
<tr>
<td>暂无信息</td>
<td>暂无信息</td>
</tr>
</table>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
shopping_car: [],
isShow: true,
},
methods: {
refresh() {
this.shopping_car = [
{name: 'Threadripper 3990X', price: '29999元'},
{name: 'NVIDIA RTX 8000', price: '59999元'},
];
this.shopping_car.push({name: 'ROG ZENITH II EXTREME', price: '9999元'});
this.isShow = false;
}
}
})
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
点击刷新购物车.
# v-for遍历
v-for遍历数组(列表)、对象(字典)、数字
注意: 在vue中!
数组 的index
和value
是 反的 ; 对象 的key
和value
也是 反的 !
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
<style>
table, td {
border: 1px solid black;
text-align: center;
}
</style>
</head>
<body>
<div id="app" style="margin: 20px">
<h3>for循环遍历</h3>
<h4> 1> 循环数字 </h4>
<ul>
<li v-for="i in number">{{i}}</li>
</ul>
<h4> 2> 数组(列表) </h4>
<ul>
<!-- 若 v-for="index in list_test" 取出来的是值!! -->
<li v-for="(value,index) in list_test">{{index}} - {{value}}</li>
</ul>
<h4> 3> 对象(字典) </h4>
<ul>
<li v-for="(value,key) in dic_test">{{key}} - {{value}}</li>
</ul>
<h4> 4> 数组(列表)套对象(字典) </h4>
<table>
<tr>
<td>姓名</td>
<td>年龄</td>
<td>性别</td>
<td>国籍</td>
</tr>
<tr v-for="info in summary_test">
<td>{{info.name}}</td>
<td>{{info.age}}</td>
<td>{{info.gender}}</td>
<td>{{info.country}}</td>
</tr>
</table>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
number: 4,
list_test: ['First', 'second', 'Third', 'Forth', 'Fifth'],
// js对象的key值可以不加引号!
dic_test: {name: 'Darker', age: 18, gender: 'male'},
summary_test: [
{name: 'Alan', age: 23, gender: 'male', country: 'America'},
{name: 'Ben', age: 15, gender: 'male', country: 'Australia'},
{name: 'Cindy', age: 12, gender: 'female', country: 'Japan'},
{name: 'Darker', age: 18, gender: 'male', country: 'China'},
{name: 'Elisa', age: 26, gender: 'female', country: 'Mexico'},
]
},
methods: {}
})
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Q: 往往给标签绑定一个属性指令:key
, 这是为什么?
特别提醒, 永远不要用数组的下标index作为key的值!!!
前端面试必问,v-for中key值的作用,diff算法是啥,但后端只需要了解即可.
A: vue中使用的是虚拟DOM,会和原生的DOM进行比较,然后进行数据的更新,提高数据的刷新速度(虚拟DOM用了diff算法)
在v-for循环数组、对象时,建议在控件/组件/标签写1个key属性,其属性值绑定一个变量,并且是动态唯一的!
页面更新之后,会加速DOM的替换(渲染),提高更新速度!
:key="变量"
参考链接: https://www.zhihu.com/question/61064119/answer/766607894
2
3
4
5
6
7
8
# 数组的检测和更新
Vue.set(this.my_l, 0, 'xxx')
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app" style="margin: 20px">
<button @click="handleClick">点击变化</button>
<p v-for="item in my_l">{{item}}</p>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
my_l: ['egon', 'lqz', 'dc']
},
methods: {
handleClick() {
// -- 通过 索引值 更新数组(数组数据会更新,但是页面不会发生改变/页面检测不到数组的更新)
// 因为作者重写了数组相关方法,但只重写了一部分方法,还有另一部分没有重写!!
// this.my_l[0] = 'xxx'
// -- 通过 Vue.set(对象, index/key, value) 更新数组(数据会更新,页面也会发生改变)
Vue.set(this.my_l, 0, 'xxx')
}
}
})
</script>
</html>
<!-- ▲ 不用记,数组更新,页面没有跟着变换,换个写法,用Vue.set()!
可以检测到变动的数组操作:
push:最后位置添加
pop:最后位置删除
shift:第一个位置删除
unshift:第一个位置添加
splice:切片
sort:排序
reverse:反转
检测不到变动的数组操作:
filter():过滤
concat():追加另一个数组
slice()
map()
-->
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# 事件处理
# 输入框v-model
前面在事件指令的地方,学习了点击事件@click.
此处学习下输入框相关的v-modl和input、change、blur事件!!
切记: v-model只针对input标签!!! 事件@input、@change、@blur也只适用于input框!
事件 | 释义 |
---|---|
@input | 只要输入框输入内容就会触发 |
@change | 当元素的值发生改变时才会触发 |
@blur | 当输入框失去焦点的时候才会触发 |
change 和 blur 最本质的区别: 若输入框为空/默认值未改变, 失去焦点后, change不会触发, 但是blur会触发!!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app" style="margin: 20px">
<!-- 不要用属性指令 :value做绑定,:value只能设置默认值 只能实现单向的绑定 -->
<!-- 用v-model既可以设置输入框的默认值,还可以通过改变输入框的值双向改变绑定变量的值!! -->
<!-- placeholder属性是灰色的提示!! -->
<input type="text" v-model="msg" placeholder="请输入内容"> {{msg}}
<p></p>
<!-- ★ blur应用场景:用户输入手机号后,在进行其它操作之前(比如输入验证码),先校验该手机号是否在数据库里!!-->
<!-- 注册时,输入用户名同理 -->
<input type="text" v-model="msg1" @blur="handleBlur" @change="handleChange"> {{msg1}}
<p></p>
<input type="text" v-model="msg2" @input="handleInput"> {{msg2}}
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: '默认值',
msg1: 'default',
msg2: '0',
},
methods: {
handleBlur() {
console.log("blur事件:", this.msg1)
},
handleChange() {
console.log("change事件:", this.msg1)
},
handleInput() {
console.log("input事件:", this.msg2)
}
}
})
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 过滤案例
示栗效果: 输入a,把带a的字符串显示出来, 显示a、at、atom; 输入at, 同理, 显示at、atom!
# 数组的过滤方法
数组对象的filter + 字符串的indexOf
<script>
var l = ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf']
// -- 数组的过滤方法filter,传递一个匿名函数进去:
// 会循环数组,将每个元素都给匿名函数的参数item..
// 在匿名函数里,写逻辑. 若return true,该元素保留; 若return false,该元素不保留.
var new_l = l.filter(function (item) {
// 字符串的indexOf方法:
// 子序列位置,未找到返回-1. 即返回索引,若值大于-1,表明子字符串在当前字符串中!
var res = item.indexOf('at')
if (res > -1) {
return true
} else {
return false
}
// 上述6行代码,可以简写, return item.indexOf('at') > -1
})
console.log(new_l) // ['at', 'atom']
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Es6箭头函数
箭头函数替换原来的匿名函数 ,箭头函数里的this和外层函数里的this是同一个this.
普通匿名函数内部的this和外层函数里的this不是同一个this!!箭头函数内部没有this,会用外部的!
<script>
// 若只有一个参数item,(item)的括号可去掉.没有或多个一定要加括号!
var new_l = l.filter((item) => {
// var res = item.indexOf('at')
// if (res > -1) {
// return true
// } else {
// return false
// }
// -- 简写方案
return item.indexOf('at') > -1
})
console.log(new_l) // ['at', 'atom']
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
# 代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app" style="margin: 20px">
<p>{{ dataList }}</p>
<input type="text" v-model="my_text" @input="handleInput">
<li v-for="item in newDataList">{{item}}</li>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
my_text: "",
// 注意: dataList的数据不是前端写死的!!是从后端加载过来的!!
dataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'],
newDataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'],
},
methods: {
// 触发input事件,让数组newDataList发生变化.
handleInput() {
// -- 写法一: 匿名函数 需要考虑this的指向问题
// var _this = this
// this.newDataList = this.dataList.filter(function (item) {
// // ★ 注意:此处该匿名函数里的this对象不是Vue对象,是windows浏览器对象!!
// // So,该匿名函数里this.my_text的结果为undefined
// return item.indexOf(_this.my_text) > -1
// })
// -- 写法一: ES6箭头函数
// 过滤dataList数组,每次从数组中拿出一个值来判断该值有没有包含输入框里输入的内容,有>-1,没有等于-1
// newDataList数组发生变化,双向绑定,页面上的<li>就会发生变化.
this.newDataList = this.dataList.filter((item) => {
return item.indexOf(this.my_text) > -1
})
// -- 究极简写
// this.newDataList = this.dataList.filter(item => item.indexOf(this.my_text) > -1)
}
}
})
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 事件修饰符
用在事件后面!!
事件修饰符 | 释义 |
---|---|
.stop | 只处理自己的事件, 父控件冒泡的事件不处理 (阻止事件冒泡 )/ 写在子控件中,不再冒泡给父标签. |
.self | 写在父控件中, 父标签只处理自己的事件, 子控件冒泡的事件不处理 |
.prevent | 事件会触发, 但会阻止a标签里链接的跳转 |
.once | 事件只会触发一次 (适用于抽奖页面) |
何为冒泡事件? 子标签和父标签都有点击事件, 点击子标签时, 父标签的点击事件会一同被触发..
解决冒泡事件, .stop
子不冒泡给父; .self
子冒泡上来的父不处理!!
a标签这样使用修饰符时, 顺序很重要; 相应的代码会以同样的顺序产生.
1> 用 v-on:click.prevent.self
会阻止 所有的点击
2> 而 v-on:click.self.prevent
只会阻止 对元素自身的点击
(不是很明白啥意思, 官方文档上这样写的. 遇到了请参考,一看就明白!!
https://blog.csdn.net/catascdd/article/details/108264406
)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
<style>
a {
text-decoration: none;
}
</style>
</head>
<body>
<div id="app" style="margin: 20px">
<!--<ul @click.self="handleUl">-->
<ul @click="handleUl">
<!-- "事件冒泡": @click="handleLi" 点击li,li的事件会冒泡到ul上!!触发ul的点击事件 -->
<!-- 若想事件冒泡在父控件ul上不生效,ul标签这样写 <ul @click.self="handleUl"> -->
<li @click="handleLi">I'm Li1,不阻止事件冒泡</li>
<!-- @click.stop="handleLi" 阻止冒泡事件,父控件ul就不会触发事件 -->
<li @click.stop="handleLi">I'm Li2,阻止事件冒泡</li>
</ul>
<p>
<!-- @click.prevent 事件会触发,但不会跳转 -->
<a href="https://www.baidu.com" @click.prevent="handleA">点击拦截</a>
</p>
<!-- @click="handleMS" 每次点击都会触发handleMS的执行-->
<!-- @click.once="handleMS" 多次点击只会触发handleMS的一次执行-->
<button @click.once="handleMS">秒杀</button>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {},
methods: {
handleUl() {
console.log('Ul被点击啦!')
},
handleLi() {
console.log('li被点击啦!')
},
handleA() {
console.log('a标签被点击啦!')
// 可在该函数里添加逻辑,满足某些条件后再跳转
// window.location = "https://www.baidu.com"
},
handleMS() {
console.log("handleMS ")
}
}
})
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# 按键修饰符
顾名思义, 跟你在键盘上按下什么键有关!! 监控用户点击哪个键.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<!-- @keyup按下任意键弹起来触发;@keydown按下就触发 一般会用@keyup -->
<!-- @keyup.enter @keyup.esc 加了限制,按下enter键和esc键 才会执行绑定的函数
若是其它键,@keyup在绑定的函数里通过event.code或者event.key判断下! -->
<div id="app" style="margin: 20px">
<!-- 在该输入框里随便输入多少内容,只有当按下enter键弹起后,才会触发绑定的函数 -->
<!-- 应用场景: 京东的搜索栏里,输入好内容后,点击回车就会向后端API发送请求 -->
<input type="text" v-model="msg1" @keyup.enter="handleUp1($event)">
<p></p>
<!-- 在该输入框里随便输入内容,只要输入一个字符,都会触发绑定的函数 -->
<input type="text" v-model="msg2" @keyup="handleUp2($event)">
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
msg1: "",
msg2: "",
},
methods: {
handleUp1(event) {
console.log(event)
},
handleUp2(event) {
console.log(event)
if (event.key == 'q'){
console.log("按到了q键.")
}
},
}
})
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
注: 根据演示结果可知, 在键盘上按下啥, 里面的key值就是啥!!
# 表单控制
# 单选、多选
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app" style="margin: 20px">
<input type="text" placeholder="请输入用户名:"><br>
<input type="password" placeholder="请输入密码:"><br>
<input type="checkbox" v-model="checkbox_one">记住用户名
<p>--- --- ---</p>
<!-- 因为在数据库里通常会存数字 所以这里1男 2女 0保密/未知-->
<input type="radio" v-model="gender" value="1">男
<input type="radio" v-model="gender" value="2">女
<input type="radio" v-model="gender" value="0">保密
<br><br>您选择的性别:{{gender}}
<p>--- --- ---</p>
<input type="checkbox" v-model="many" value="0">篮球
<input type="checkbox" v-model="many" value="1">足球
<input type="checkbox" v-model="many" value="2">棒球
<input type="checkbox" v-model="many" value="3">桌球
<br><br>您喜欢的球类:{{many}}
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
myText: '',
textBig: '',
// 如果只是一个checkbox,绑定的值就是true和false.
checkbox_one: false,
// redio单选,是字符串,选择谁,字符串就变成选中的value值.
gender: '',
// checkbox多选,绑定的值就是数组,选择以后,数组中放选中的value值.
many: [],
},
methods: {}
})
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 购物车案例: 结算
注意, 插值语法里带函数, 页面一变化/更新, 该函数会重新计算!!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
<style>
table, td {
border: 1px solid black;
text-align: center;
}
</style>
</head>
<body>
<div id="app" style="margin: 20px">
<table>
<tr>
<td>商品名称</td>
<td>价格</td>
<td>数量</td>
<td>选择</td>
</tr>
<tr v-for="item in dataList">
<td>{{item.name}}</td>
<td>{{item.price}}</td>
<td>{{item.number}}</td>
<!-- value="item" 不管循环多少次 绑定的都是写死的字符串"item" -->
<!-- 属性指令 :value="item" 绑定了item,循环出的item是谁这里就是谁,item是一个对象-->
<!-- 多选,选中的,会将value值放到checkGroup数组里 -->
<td><input type="checkbox" v-model="checkGroup" :value="item"></td>
</tr>
</table>
<br>已选商品:{{checkGroup}}
<br>总价:{{getPrice()}}
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
// 数据可通过ajax请求从后端加载过来.
dataList: [
{name: '今瓶没', price: 99, number: 2},
{name: '西柚记', price: 59, number: 1},
{name: '水壶转', price: 89, number: 5},
],
checkGroup: [],
},
methods: {
getPrice() {
let total = 0
// -- 循环方式1
for (let i = 0; i < this.checkGroup.length; i++) {
let obj = this.checkGroup[i]
total = total + obj.price * obj.number
}
return total
/*
// -- 循环方式2
for (i in this.checkGroup) { // 这里i是索引
let obj = this.checkGroup[i]
total += obj.price * obj.number
}
return total
// -- 循环方式3 es6的of循环方式
for (v of this.checkGroup) { // 这里v是数组中的每一个对象
total += v.price * v.number
}
return total
// -- 循环方式4 对象的迭代方法 它也挺常用的!
// 里面是一个匿名函数,可以用箭头函数替换!
this.checkGroup.forEach(function (value, index) {
total += value.price * value.number
})
return total
*/
}
}
})
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# 购物车案例: 全选全不选
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
<style>
table, td {
border: 1px solid black;
text-align: center;
}
</style>
</head>
<body>
<div id="app" style="margin: 20px">
<table>
<tr>
<td>商品名称</td>
<td>价格</td>
<td>数量</td>
<td>
选择
<!-- 全选/全不选 这个框是单独的 选中checkAll的值为true,不选中值为false -->
<!-- input框的值改变触发 handleAll 函数的执行 -->
<input type="checkbox" v-model="checkAll" @change="handleAll">
</td>
</tr>
<tr v-for="item in dataList">
<td>{{item.name}}</td>
<td>{{item.price}}</td>
<td>{{item.number}}</td>
<!-- 这里绑定了一个change事件 全选的话,选择那里的框要自动打上勾 -->
<td><input type="checkbox" v-model="checkGroup" :value="item" @change="checkone"></td>
</tr>
</table>
<br>已选商品:{{checkGroup}}
<br>总价:{{getPrice()}}
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
dataList: [
{name: '今瓶没', price: 99, number: 2},
{name: '西柚记', price: 59, number: 1},
{name: '水壶转', price: 89, number: 5},
],
checkGroup: [],
checkAll: false,
},
methods: {
getPrice() {
let total = 0
for (v of this.checkGroup) {
total += v.price * v.number
}
return total
},
handleAll() {
if (this.checkAll) {
// 用户全选了
this.checkGroup = this.dataList
} else {
// 用户全不选
this.checkGroup = []
}
},
checkone() {
// 需判断,checkGroup的长度是否等于dataList的长度
// 若等于证明用户全选了,需将checkAll置为true. 否则置为false.
if (this.checkGroup.length === this.dataList.length) {
this.checkAll = true
} else {
this.checkAll = false
}
// 上面5行代码可以简写成下面一行代码.
// this.checkAll = (this.checkGroup.length == this.dataList.length)
}
}
})
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# 购物车案例: 数量加减
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
<style>
table, td {
border: 1px solid black;
text-align: center;
}
</style>
</head>
<body>
<div id="app" style="margin: 20px">
<table>
<tr>
<td>商品名称</td>
<td>价格</td>
<td>数量</td>
<td>
选择
<input type="checkbox" v-model="checkAll" @change="handleAll">
</td>
</tr>
<tr v-for="item in dataList">
<td>{{item.name}}</td>
<td>{{item.price}}</td>
<td>
<!-- 需求: 实现商品数量加减. -->
<button @click="handleJian(item)">-</button>
{{item.number}}
<button @click="item.number++">+</button>
</td>
<td><input type="checkbox" v-model="checkGroup" :value="item" @change="checkone"></td>
</tr>
</table>
<br>已选商品:{{checkGroup}}
<br>总价:{{getPrice()}}
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
dataList: [
{name: '今瓶没', price: 99, number: 2},
{name: '西柚记', price: 59, number: 1},
{name: '水壶转', price: 89, number: 5},
],
checkGroup: [],
checkAll: false,
},
methods: {
getPrice() {
let total = 0
for (v of this.checkGroup) {
total += v.price * v.number
}
return total
},
handleAll() {
if (this.checkAll) {
this.checkGroup = this.dataList
} else {
this.checkGroup = []
}
},
checkone() {
this.checkAll = this.checkGroup.length === this.dataList.length;
},
// 需要把是哪个商品传进了,即传item
handleJian(item) {
if (item.number > 1) {
item.number--
} else {
alert("不能再减少啦!")
// item.number = 1
}
}
}
})
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# v-model进阶
lazy : 等待input框的数据绑定时区焦点之后再变化
number : 数字开头, 只保留数字, 后面的字母不保留; 字母开头,都保留.
trim : 去除输入内容前后的空格
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app" style="margin: 20px">
<!-- 因为双向绑定了,输入框的值有一点点变化,{{myText1}}渲染的内容就会跟着一起变. 输入的过程,都在渲染.比较耗费资源! -->
<input type="text" v-model="myText1" placeholder="normal"> {{myText1}}
<p></p>
<!-- 小优化,光标从输入框中移除后,输入框右边才显示输入的内容. -->
<input type="text" v-model.lazy="myText2" placeholder="lazy"> {{myText2}}
<p></p>
<!-- 数字开头,只保留数字,后面的字母不保留; 字母开头,都保留. -->
<input type="text" v-model.number="myText3" placeholder="number"> {{myText3}}
<p></p>
<!-- 去除前后的空格 -->
<input type="text" v-model.trim="myText4" placeholder="trim"> {{myText4}}
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
myText1: "",
myText2: "",
myText3: "",
myText4: "",
},
methods: {}
})
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35