30no2's Blog.

vue.js笔记二

字数统计: 4.1k阅读时长: 21 min
2021/05/19 Share

1、Es6一些基础语法及增强

1.1、let/var

let可以看作是更完美的var,js在使用var声明变量的时候,变量的作用域主要是和函数的定义有关.而对于没有作用域的比如if/for等会出现问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//es5
var btns = document.getElementsByTagName('button');
for (var i=0; i<btns.length; i++) {
(function (num) { // 0
btns[i].addEventListener('click', function () {
console.log('第' + num + '个按钮被点击');
})
})(i)
}
//es6
let btns = document.getElementsByTagName('button')
for (let i = 0; i < btns.length; i++) {
btns[i].addEventListener('click', function () {
console.log('第' + i + '个按钮被点击');
})
}

1.2、const的使用

const修饰的标识符为常量,不可以再次赋值,但是可以修改const内部的属性

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>

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

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

// 3.注意三: 常量的含义是指向的对象不能修改, 但是可以改变对象内部的属性.
const obj = {
name: 'why',
age: 18,
height: 1.88
}
// obj = {}
console.log(obj);

obj.name = 'kobe';
obj.age = 40;
obj.height = 1.87;

console.log(obj);
</script>

</body>
</html>

1.3、ES6中的对象增强的写法

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>

<script>
// const obj = new Object()

// const obj = {
// name: 'why',
// age: 18,
// run: function () {
// console.log('在奔跑');
// },
// eat: function () {
// console.log('在次东西');
// }
// }

// 1.属性的增强写法
const name = 'why';
const age = 18;
const height = 1.88

// ES5的写法
// const obj = {
// name: name,
// age: age,
// height: height
// }

// const obj = {
// name,
// age,
// height,
// }
//
// console.log(obj);

// 2.函数的增强写法
// ES5的写法
// const obj = {
// run: function () {
//
// },
// eat: function () {
//
// }
// }
const obj = {
run() {

},
eat() {

}
}
</script>

</body>
</html>

1.4、v-on详细说明

1.4.1、参数

  • 如果该方法不需要额外参数,那么方法后的()可以不添加。但是注意:如果方法本身中有一个参数,那么会默认将原生事件event参数传递进去
  • 如果需要同时传入某个参数,同时需要event时,可以通过$event传入事件。
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>

<div id="app">
<!--1.事件调用的方法没有参数-->
<button @click="btn1Click()">按钮1</button>
<button @click="btn1Click">按钮1</button>

<!--2.在事件定义时, 写方法时省略了小括号, 但是方法本身是需要一个参数的, 这个时候, Vue会默认将浏览器生产的event事件对象作为参数传入到方法-->
<!--<button @click="btn2Click(123)">按钮2</button>-->
<!--<button @click="btn2Click()">按钮2</button>-->
<button @click="btn2Click">按钮2</button>

<!--3.方法定义时, 我们需要event对象, 同时又需要其他参数-->
<!-- 在调用方式, 如何手动的获取到浏览器参数的event对象: $event-->
<button @click="btn3Click(abc, $event)">按钮3</button>
</div>

<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
abc: 123
},
methods: {
btn1Click() {
console.log("btn1Click");
},
btn2Click(event) {
console.log('--------', event);
},
btn3Click(abc, event) {
console.log('++++++++', abc, event);
}
}
})

// 如果函数需要参数,但是没有传入, 那么函数的形参为undefined
// function abc(name) {
// console.log(name);
// }
//
// abc()
</script>

</body>
</html>

1.4.2、修饰符

  • Vue提供了修饰符来帮助我们方便的处理一些事件:
    • .stop - 调用 event.stopPropagation()。
    • .prevent - 调用 event.preventDefault()。
    • .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
    • .native - 监听组件根元素的原生事件。
    • .once - 只触发一次回调。
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>

<div id="app">
<!--1. .stop修饰符的使用-->
<div @click="divClick">
aaaaaaa
<button @click.stop="btnClick">按钮</button>
</div>

<!--2. .prevent修饰符的使用-->
<br>
<form action="baidu">
<input type="submit" value="提交" @click.prevent="submitClick">
</form>

<!--3. .监听某个键盘的键帽-->
<input type="text" @keyup.enter="keyUp">

<!--4. .once修饰符的使用-->
<button @click.once="btn2Click">按钮2</button>
</div>

<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
methods: {
btnClick() {
console.log("btnClick");
},
divClick() {
console.log("divClick");
},
submitClick() {
console.log('submitClick');
},
keyUp() {
console.log('keyUp');
},
btn2Click() {
console.log('btn2Click');
}
}
})
</script>

</body>
</html>

1-5、v-if/v-else/v-else-if

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<div v-if="isShow">
<div>{{ message + 'hello1' }}</div>
</div>
<div v-else-if="isHappy">hhhhh</div>
<div v-else>{{ message +'2'}}</div>
</div>

<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
const app = new Vue({
el:'#app',
data:{
message:"hello vue",
isShow:false,
isHappy:true
}
});
</script>
</body>
</html>

1.5.1、原理

v-if 后面的条件为false 的时候,对应的元素以及子元素不会渲染

1.5.2、案例

  • vue在进行DOM渲染的时候,处于性能考虑,会尽可能的复用已经存在的元素,而不是重新创建新的元素,如果我们不希望Vue出现重复利用的问题,可以给对应的input添加key,并且保证key的不同
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<form action="#">
<span v-if="isY">
<label for="username">用户登录</label>
<!-- 防止复用之前缓存 -->
<input type="text" id="username" placeholder="用户登录" key="username">
</span>
<span v-else>
<label for="email">邮箱登录</label>
<input type="text" id="email" placeholder="邮箱登录" key="email" key="email">
</span>

<button @click="changeMy()">切换用户</button>
</form>
</div>

<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
const app = new Vue({
el:'#app',
data:{
message:"hello vue",
isY:true
},
methods:{
changeMy(){
this.isY = !this.isY
}
}
});
</script>
</body>
</html>

1-6、v-show的使用

  • v-show当条件为false的时候仅仅是将元素的display的属性设置为none,而v-if 则是压根不会渲染DOM
  • 开发中,当现实与隐藏很频繁的时候,使用v-show当只有一次显示的时候使用v-if

1-7、v-for遍历对象/数组

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<div>{{ message }}</div>
<ul>
<!-- 普通的用法-->
<!-- <li v-for="item in books">{{item}}</li>-->
<!-- 获取序列号-->
<!-- <li v-for="(item,index) in books">{{item}}&#45;&#45;{{index}}</li>-->
<!-- 获取id和序列号-->
<li v-for="(item,key,index) in salary" :key="item">{{item}}--{{key}}--{{index}}</li>
</ul>
</div>

<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
const app = new Vue({
el:'#app',
data:{
message:"hello vue",
books:['西游记','三国演义','水浒传','红楼梦'],
salary:{
'no1': 100,
'no2': 200,
'no3': 300,
}
}
});
</script>
</body>
</html>
  • 官方推荐我们在使用v-for时,给对应的元素或组件添加上一个:key属性。并保证这个属性是唯一的,这样Diff算法可以正确的识别此节点,找到正确的位置区插入新的节点,所以说key的作用是为了高效的更新虚拟DOM

1-8、检测数据更新

push() 向数组末尾添加数据
pop() 删除数组最后的数据
shift() 删除数组开头的数据
unshift() 从开始位置添加数据
splice() 从第几的位置删除数据,或者添加数据插入
sort() 正序排序(按照数组)
reverse() 反转数组
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
<div id="app">
<ul>
<li v-for="item in data">{{item}}</li>
</ul>
<button @click="updateData()">按钮</button>
</div>

<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
const app = new Vue({
el:'#app',
data:{
message:"hello vue",
data:['a','c','b','d']
},
methods:{
updateData(){
// 1、push() 向数组末尾添加数据
// this.data.push('aaa','ddd')
//2、pop() 删除数组最后的数据
// this.data.pop()
//3、shift() 删除数组开头的数据
// this.data.shift()
//4、unshift() 从开始位置添加数据
// this.data.unshift('why')
//5、splice() 从第几的位置删除数据,或者添加数据插入
// this.data.splice(1,0,'hello')//从第二的位置插入数据
// this.data.splice(1,1,'hello')//从第二的位置修改数据
// this.data.splice(1,2)//从第二的位置删除两个数据
//6、sort() 正序排序(按照数组)
// this.data.sort()
//7、reverse() 反转数组
this.data.reverse()
}
}
});
</script>

1.9、图书购物车(案例)

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div id="app">
<div v-if="books.length">
<table>
<tr>
<th></th>
<th>书籍名称</th>
<th>出版日期</th>
<th>价格</th>
<th>购买数量</th>
<th>操作</th>
</tr>
<tbody>
<tr v-for="(item,index) in books">
<th>{{item['id']}}</th>
<th>{{item['name']}}</th>
<th>{{item['date']}}</th>
<th>{{item['price'] | showPrice}}</th>
<th>
<button @click="decrement(index)" v-bind:disabled="item.number<=1">-</button>
{{item['number']}}
<button @click=increment(index)>+</button>
</th>
<th><button @click=removeHandle(index)>删除</button></th>
</tr>
</tbody>
</table>
<div>总价格{{totalPrice | showPrice}}</div>
</div>
<div v-else>购物车为空</div>
</div>

<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script src="main.js"></script>

</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
table{
border:1px solid #e9e9e9;
border-collapse: collapse;
border-spacing: 0;
}
th,td{
padding:8px 16px;
border:1px solid #e9e9e9;
text-align: left;
}

th{
background-color: #f7f7f7;
color:#5c6b77;
font-weight: 600;
}
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
const app = new Vue({
el:'#app',
data:{
books:[{
"id":1,
"name":"《算法导论》",
"date":'2006-01',
"price":85.00,
"number":1
},{
"id":2,
"name":"《算法导论》",
"date":'2006-01',
"price":85.00,
"number":1
},{
"id":3,
"name":"《算法导论》",
"date":'2006-01',
"price":85.00,
"number":1
},{
"id":4,
"name":"《算法导论》",
"date":'2006-01',
"price":85.00,
"number":1
}]
},
methods:{
decrement(index){
this.books[index].number--
},
increment(index){
this.books[index].number++
},
removeHandle(index) {
this.books.splice(index, 1)
}

},
computed:{
totalPrice(){
let totalPrice = 0
for (let i = 0; i < this.books.length; i++) {
totalPrice += this.books[i].price * this.books[i].number
}
return totalPrice
}
},
filters:{
showPrice(price){
return '¥'+price.toFixed(2)
}
}
})

2.0、高阶函数的js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//高阶函数的使用
//filter函数 返回true则会把n加到新数组中。false则不会
const num = [20,30,40,21,22,40]
let nums = num.filter(function (n) {
return n<30
})
//map函数 便利数组,返回计算后的值
let nums = num.map(function (n) {
return n*2
})
//reduce函数
let nums = num.reduce(function (previousValue,n) {
return previousValue+n
},0)
//函数式编程链式操作
let nums = num.filter(function (n) {
return n<30
}).map(function (n) {
return n*2
}).reduce(function (previousValue,n) {
return previousValue+n
},0)
let nums = num.filter(n=>n<30).map(n=>n*2).reduce(((previousValue,n)=>previousValue+n),0);
console.log(nums);

2.1、v-model 原理

2.1.1、基本原理

v-model 是 v-bind和v-on 的指令的结合

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
<body>
<div id="app">
<!-- <input type="text" v-model="message">-->
<!-- v-model实际上是两个指令的合计 v-on 和 v-bind:input-->
<!-- <input type="text" v-bind:value="message" v-on:input="myChange">-->
<!-- 简便写法-->
<input type="text" :value="message" @input="message = $event.target.value">
<div>{{ message }}</div>
</div>

<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
const app = new Vue({
el:'#app',
data:{
message:"hello vue"
},
methods:{
myChange(event){
this.message = event.target.value
}
}
});
</script>
</body>

2.1.2、v-model在单选/多选/复选框/下拉框 之间的使用

  • radio

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <div id="app">
    <label for="mail">
    <input type="radio" value="男" v-model="sex" name="sex" id="mail">
    </label>
    <label for="famail">
    <input type="radio" value="女" v-model="sex" name="sex" id="famail">
    </label>

    <div>{{ message }} 您选择的是 {{sex}}</div>
    </div>

    <!--导入vue.js-->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
    <script>
    const app = new Vue({
    el:'#app',
    data:{
    message:"hello vue",
    sex:'女'
    }
    });
    </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
    27
    28
    29
    <div id="app">
    <!--单选框-->
    <!-- <label for="agree">-->
    <!-- <input type="checkbox" id="agree" v-model="isAgree" > 同意协议-->
    <!-- </label>-->
    <!-- <div>你选择的是:{{isAgree}}</div>-->
    <!-- <button v-bind:disabled="!isAgree">下一步</button>-->
    <!-- 多选框-->
    <label for="id1">
    <input id="id1" type="checkbox" value="篮球1" v-model="hobby">篮球1</label>
    <label for="id2">
    <input id="id2" type="checkbox" value="篮球2" v-model="hobby">篮球2</label>
    <label for="id3">
    <input id="id3" type="checkbox" value="篮球3" v-model="hobby">篮球3</label>
    您的爱好是:{{hobby}}
    </div>

    <!--导入vue.js-->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
    <script>
    const app = new Vue({
    el:'#app',
    data:{
    message:"hello vue",
    isAgree:false,
    hobby:[]
    }
    });
    </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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    <div id="app">
    <select name="abc" id="" v-model="fruit">
    <option value="苹果1" >苹果1</option>
    <option value="苹果2" >苹果2</option>
    <option value="苹果3" >苹果3</option>
    <option value="苹果4" >苹果4</option>
    <option value="苹果5" >苹果5</option>
    <option value="苹果6" >苹果6</option>
    </select>

    <div>您选择的水果是:{{fruit}}</div>

    <select name="abc" v-model="fruits" multiple>
    <option value="苹果1" >苹果1</option>
    <option value="苹果2" >苹果2</option>
    <option value="苹果3" >苹果3</option>
    <option value="苹果4" >苹果4</option>
    <option value="苹果5" >苹果5</option>
    <option value="苹果6" >苹果6</option>
    </select>
    <div>您选择的水果是:{{fruits}}</div>
    </div>

    <!--导入vue.js-->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
    <script>
    const app = new Vue({
    el:'#app',
    data:{
    message:"hello vue",
    fruit:'苹果1',
    fruits:['苹果1','苹果2']
    }
    });
    </script>

2.1.3、值绑定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div id="app">
<select name="abc" multiple>
<option v-for="item in fruits" :value="item" >{{item}}</option>
</select>
<div>您选择的水果是:{{fruits}}</div>
</div>

<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
const app = new Vue({
el:'#app',
data:{
message:"hello vue",
fruit:'苹果1',
fruits:['苹果1','苹果2']
}
});
</script>

2.1.4、v-model修饰符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div id="app">

<!-- lazy:当失去焦点或者回车的时候才会更新message-->
<input type="text" v-model.lazy="message">
<!-- number:更新message的时候类型为number-->
<input type="number" v-model.number="message">
<!-- trim:修改输入框中左右两边的空格-->
<input type="text" v-model.trim="message">
<br>
{{message}}-----{{typeof message}}

</div>

<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
const app = new Vue({
el:'#app',
data:{
message:"hello vue"
}
});
</script>
CATALOG
  1. 1. 1、Es6一些基础语法及增强
    1. 1.1. 1.1、let/var
    2. 1.2. 1.2、const的使用
    3. 1.3. 1.3、ES6中的对象增强的写法
    4. 1.4. 1.4、v-on详细说明
      1. 1.4.1. 1.4.1、参数
    5. 1.5. 1-5、v-if/v-else/v-else-if
      1. 1.5.1. 1.5.1、原理
      2. 1.5.2. 1.5.2、案例
    6. 1.6. 1-6、v-show的使用
    7. 1.7. 1-7、v-for遍历对象/数组
    8. 1.8. 1-8、检测数据更新
    9. 1.9. 1.9、图书购物车(案例)
    10. 1.10. 2.0、高阶函数的js
    11. 1.11. 2.1、v-model 原理
      1. 1.11.1. 2.1.1、基本原理
      2. 1.11.2. 2.1.2、v-model在单选/多选/复选框/下拉框 之间的使用
      3. 1.11.3. 2.1.3、值绑定
      4. 1.11.4. 2.1.4、v-model修饰符