06方法-计算属性-监听器
# 方法、计算属性、监听器
# 方法
存放函数的地方
<div id="app">
<form>
<input type="text" @input="fn($event)">
{{msg}}
</form>
</div>
<script>
//语法糖
new Vue({
el: "#app",
data: {
msg: "",
},
methods: {
fn1() {
console.log(123);
},
fn2() {
this.fn1();
},
},
created() {
this.fn2();
},
});
</script>
1
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
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
# 计算属性
{{myreverse}}
new Vue({
el: "#app",
data: {
msg:"hello world"
},
computed:{//计算属性
myreverse(){
return this.msg.split("").reverse().join("")
}
}
});
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
[!cogs]
%accordion% 🚀 %accordion%
<div id="app">
<div>{{reverse}}</div>
</div>
<script>
new Vue({
el: "#app",
data: {
msg: "hello world",
},
computed: {
reverse() {
//console.log(this.msg.split("")); //(11) ["h", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d"]
//console.log(this.msg.split("").reverse("")); //(11) ["d", "l", "r", "o", "w", " ", "o", "l", "l", "e", "h"]
return this.msg.split("").reverse("").join("")//dlrow olleh
},
},
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
%/accordion%
计算属性get、set写法
姓:<input type="text" v-model="firstName"></br>
名:<input type="text" v-model="lastName"></br>
全名:<input type="text" v-model="fullName">
new Vue({
el: "#app",
data: {
firstName:"",
lastName:"",
},
computed:{//计算属性
// fullName(){
// return this.firstName + this.lastName
// }
fullName:{
get(){//获取,跟不写是一样的,这里的作用只是为了引申出set
return this.firstName + this.lastName
},
set(newVal){//修改
console.log(newVal)//返回新的fullName
}
}
}
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
%accordion% 练习🚀%accordion%
<div id="app">
<input type="text" v-model="reverse">
</div>
<script>
new Vue({
el: "#app",
data: {
msg: "hello world"
},
computed: {
reverse: {
get() {
//get属性没有任何意义,只有为了引申出后面的set
return this.msg.split("").reverse().join("")
},
set(newVal) {
console.log(newVal);
}
}
}
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
%/accordion%
# 监听器
当data数据发生变化的时候,返回变化的数据
<input type="text" v-model="msg">
{{msg}}
new Vue({
el: "#app",
data: {
msg:""
},
watch:{
msg(newVal,oldVal){
console.log(newVal)//新的值
console.log(oldVal)//旧的值
}
}
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 默认监听
<input type="text" v-model="msg">
{{msg}}
new Vue({
el: "#app",
data: {
msg:"123"
},
watch:{
msg:{
handler(newVal){//句柄,无任何含义,目的只是为了引申出后面的属性
console.log(newVal)//新的值
},
immediate:true//默认监听
}
}
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
%accordion% 练习🚀 %accordion%
<div id="app">
<input type="text" v-model="num">
</div>
<script>
new Vue({
el: "#app",
data: {
num: 1,
},
watch: {
num(newVal) {
console.log(newVal);
}
}
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
%/accordion%
# 深度监听
<input type="text" v-model="msg.name">
new Vue({
el: "#app",
data: {
msg:{
name:"小明"
}
},
watch:{
msg:{
handler(newVal){//句柄,无任何含义,目的只是为了引申出后面的属性
console.log(newVal)//新的值
},
immediate:true,//默认监听
deep:true//深度监听(用于监听引用类型数据)
}
}
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
%accordion% 练习🚀 %accordion%
<div id="app">
<input type="text" v-model="obj.num" />
</div>
<script>
new Vue({
el: "#app",
data: {
obj: {
name: "张三",
},
},
watch: {
obj: {
handler(newVal) {
//句柄,没有任何含义,为了引申出后面的属性
console.log(newVal);
},
immediate: true, //默认监听
deep: true, //深度监听,可以监听对象类型数据
},
},
});
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
%/accordion%
# 练习
1、做一个城市二级联动功能
2、购物车功能
1)购买数量需要大于等于1的正整数
2)小计功能
3)商品总计,勾选的才计算
4)当所有的勾选框都有勾选的时候,最顶部的勾选框要显示勾选
5)全选功能/反选功能
6)商品价钱、数量、小计要做排序功能
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<select name="country" v-model="country">
<option value="">==请求选择国家==</option>
<option v-for="item of arr" :value="item.countryName">{{item.countryName}}</option>
</select>
<select name="city" v-model="city">
<option value="">==请求选择城市==</option>
<option v-for="item of cities" :value="item.cityName">{{item.cityName}}</option>
</select>
</div>
<script src="<https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js>"></script>
<script>
new Vue({
el: "#app",
data: {
country:"",
cities:[],
arr: [
{
countryName: "中国",
cities: [
{ cityName: "广州" },
{ cityName: "东莞" },
{ cityName: "佛山" },
],
},
{
countryName: "美国",
cities: [
{ cityName: "洛杉矶" },
{ cityName: "纽约" },
{ cityName: "华盛顿" },
],
},
{
countryName: "日本",
cities: [
{ cityName: "东京" },
{ cityName: "大阪" },
{ cityName: "北海道" },
],
},
],
},
watch:{
country(newCountry){
let newCities = []
this.arr.forEach((item)=>{
if(item.countryName === newCountry){
newCities = item.cities
}
})
this.cities = newCities
}
}
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<table border="1" cellspacing="0">
<tr>
<td>
<input type="checkbox" v-model="allChecked" />
</td>
<td>商品名称</td>
<td>
商品价格
<button @click="priceUp">上</button>
<button @click="priceDown">下</button>
</td>
<td>商品数量</td>
<td>商品小计</td>
</tr>
<tr v-for="(item,idx) of arr">
<td>
<input type="checkbox" v-model="item.isChecked" />
</td>
<td>{{item.name}}</td>
<td>{{item.price}}</td>
<td>
<input
type="number"
v-model="item.num"
@change="changeNum(item.num,idx)"
/>
</td>
<td>{{item.price * item.num}}</td>
</tr>
</table>
总计:{{allTotal}}
</div>
<script src="<https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js>"></script>
<script>
new Vue({
el: "#app",
data: {
arr: [
{ name: "苹果13", price: 5000, num: 1, isChecked: true },
{ name: "华为p50", price: 6000, num: 2, isChecked: true },
{ name: "小米14", price: 7000, num: 3, isChecked: true },
],
},
methods: {
changeNum(num, idx) {
//改变数量
let n = Number(num);
if (n >= 1 && Number.isInteger(n)) {
this.arr[idx].num = n;
} else {
this.arr[idx].num = 1;
}
},
priceUp(){//价格由小到大排序
this.arr.sort((a,b)=>{
return a.price - b.price
})
},
priceDown(){//价格由大到小排序
this.arr.sort((a,b)=>{
return b.price - a.price
})
}
},
computed: {
allTotal() {
//总计
let sum = 0;
this.arr.forEach((item) => {
if (item.isChecked) {
sum += item.price * item.num;
}
});
return sum;
},
allChecked: {
//全选
get() {
return this.arr.every((item) => {
return item.isChecked;
});
},
set(newVal) {
if(newVal){
this.arr.map((item)=>{
item.isChecked = true
})
}else{
this.arr.map((item)=>{
item.isChecked = false
})
}
},
},
},
});
</script>
</body>
</html>
1
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
编辑 (opens new window)
上次更新: 2023/08/06, 00:38:41