上一篇文章
> Vue入门与安装
一、块级作用域(let和var)
1、块级作用域问题(ES5)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<script>
var btns = document.getElementsByTagName('button');
for (var i=0;i<btns.length; i++) {
// 闭包可以解决,但是太麻烦,函数一个作用域
btns[i].addEventListener('click', function () {
console.log('第'+ i + '个按钮被点击')
})
}
</script>
</body>
</html>
2、作用域解决(ES6)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<script>
// var btns = document.getElementsByTagName('button');
// for (var i=0;i<btns.length; i++) {
// 闭包可以解决,但是太麻烦,函数一个作用域
// btns[i].addEventListener('click', function () {
// console.log('第'+ i + '个按钮被点击')
// })
// }
const btns = document.getElementsByTagName('button');
for (let i = 0; i < btns.length; i++){
btns[i].addEventListener('click', function () {
console.log('第'+ i + '个按钮被点击')
})
}
</script>
</body>
</html>
3、const使用
使用const修饰的标识符为常量,不可以再次赋值,只有需要改变标识符的时候才使用let
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
// 1、不可以修改
// const name = 'yyy';
// name = 'abc'
//
// 2、const定义标识符,必须赋值
// const name;
// 3、 常量的含义是指向的对象不能修改,但是可以改变对象内部的属性
const obj = {
name: 'yyy',
age: 18,
height: 180
};
obj.name = 'kobe';
obj.age = 30;
obj.height = 1.70;
console.log(obj);
</script>
</body>
</html>
4、对象字面量的增强写法
<1> 属性增强写法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
// const obj = {
// name: 'yyy',
// age: 18,
// run: function () {
// console.log('run')
// }
// }
// 属性的增强写法
const name = 'yyy';
const age = 18;
const height = 1.88;
// ES5写法
// const obj = {
// name: name,
// age: age,
// height: height
// }
// ES6写法
const obj = {
name,
age,
height
};
console.log(obj);
</script>
</body>
</html>
<2> 函数增强写法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
// const obj = {
// name: 'yyy',
// age: 18,
// run: function () {
// console.log('run')
// }
// }
// 函数的增强写法
//ES5写法
// const obj = {
// run: function () {
//
// },
// eat: function () {
//
// }
// }
// ES6写法
const obj = {
run() {
},
eat() {
}
}
</script>
</body>
</html>
二、v-on事件监听
1、v-on的基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1>{{counter}}</h1>
<!--<button v-on:click="counter++">+</button>-->
<!--<button v-on:click="counter--">-</button>-->
<button v-on:click="increment">+</button>
<!--语法糖写法-->
<button @click="decrement">-</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
counter: 0
},
methods: {
increment() {
this.counter++
},
decrement() {
this.counter--
}
}
})
</script>
</body>
</html>
2、v-on参数问题
如果该方法不需要
额外参数
,那么方法后的()可以不添加
如果需要同时传入某个参数,同时需要event时,可以通过$event传入事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--事件调用的方法没有参数-->
<button @click="btn1Click">按钮1</button>
<button @click="btn1Click()">按钮1</button>
<!--在事件定义时,写方法时省略了小括号,但是本身是需要一个参数,这个时候,
Vue会默认将浏览器生成的event事件对象作为参数传入到方法中-->
<button @click="btn2Click('btn2Click')">按钮2</button>
<button @click="btn2Click()">按钮2</button>
<!--这样会传入event事件-->
<button @click="btn2Click">按钮2</button>
<!--同时需要event对象,又需要参数, 需要手动获取event对象:$event-->
<button @click="btn3Click">按钮3</button>
<button @click="btn3Click('abc', $event)">按钮3</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'hello,Vue'
},
methods: {
btn1Click() {
console.log('btn1Click');
},
btn2Click(event) {
console.log('----------',event);
},
btn3Click(abc, event) {
console.log('@@@@@@@@@@',abc, event)
}
}
})
</script>
</body>
</html>
3、v-on的修饰符
(1).stop
阻止事件冒泡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<div>
<div @click="divClick">
aaa
<button @click.stop="btnClick">按钮</button>
</div>
</div>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'hello,Vue'
},
methods: {
btnClick() {
console.log("btnClick");
},
divClick() {
console.log('divClick')
}
}
})
</script>
</body>
</html>
(2).prevent
阻止默认行为
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<div>
<form action="baidu">
<input type="submit" value="提交" @click.prevent="submitClick">
</form>
</div>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'hello,Vue'
},
methods: {
submitClick() {
console.log('submitClick');
}
}
})
</script>
</body>
</html>
(3).键别名
这里用enter键做演示,不加.enter时,只要松开按键,都会打印console.log,加入.enter后只有松开enter键才会
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<div>
<!--监听某个键盘键点击-->
<input type="text" @keyup.enter="keyUp">
</div>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'hello,Vue'
},
methods: {
keyUp() {
console.log('keyup');
}
}
})
</script>
</body>
</html>
(4).once
只能调用一次
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<div>
<!--.once-->
<button @click.once="btn2Click">按钮2</button>
</div>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'hello,Vue'
},
methods: {
btn2Click() {
console.log('btn2Click');
}
}
})
</script>
</body>
</html>
三、条件判断
1、v-if使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1 v-if="false">{{message}}</h1>
<h1 v-if="true">{{message}}</h1>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'hello,Vue'
}
})
</script>
</body>
</html>
2、v-if和v-else使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1 v-if="isShow">
{{message}}
</h1>
<h1 v-else>isShow为false</h1>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'hello,Vue',
isShow: true
}
})
</script>
</body>
</html>
3、v-if和v-else-if和v-else使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1 v-if="score>=90">优秀</h1>
<h1 v-else-if="score>=80">良好</h1>
<h1 v-else-if="score>=60">及格</h1>
<h1 v-else>不及格</h1>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
score: 98
}
})
</script>
</body>
</html>
4、用户登录切换案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<span v-if="isUser">
<label for="username">用户账号</label>
<input type="text" id="username" placeholder="用户账号">
</span>
<span v-else>
<label for="email">用户邮箱</label>
<input type="text" id="email" placeholder="用户邮箱">
</span>
<button @click="isUser = !isUser">切换类型</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
isUser: true
}
})
</script>
</body>
</html>
如果不想input进行复用,就添加不用的key
5、v-show使用
频率高的切换就使用v-show,否则v-if
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--v-if: 当条件为flalse时,包含v-if指令的元素,不会存在dom中-->
<!--v-show: 当条件为false时,v-show只是给我们元素添加了一个行内样式 ==> display: none-->
<h1 v-if="isShow" id="a">{{message}}</h1>
<h1 v-show="isShow" id="b">{{message}}</h1>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'hello,Vue',
isShow: true
}
})
</script>
</body>
</html>
四、循环遍历
1、v-for遍历数组
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--没有使用索引值-->
<ul>
<li v-for="item in names">{{item}}</li>
</ul>
<!--获取索引值-->
<ul>
<li v-for="(item,index) in names">{{index+1}}.{{item}}</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
names: ['kobe', 'james']
}
})
</script>
</body>
</html>
2、v-for遍历对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--获取一个值,那么获取的是value-->
<ul>
<li v-for="item in info">{{item}}</li>
</ul>
<!--获取key和value ==> (value,key)-->
<ul>
<li v-for="(value,key) in info">{{value}}-{{key}}</li>
</ul>
<!--获取key、value、index ==> (value, key, index)-->
<ul>
<li v-for="(value, key, index) in info">{{value}}-{{key}}-{{index}}</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
info: {
name: 'yyy',
age: 18,
height: 1.88
}
}
})
</script>
</body>
</html>
3、v-for使用过程添加
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--加入key保证唯一性,这样插入值时,效率更高,不会逐个修改-->
<ul>
<li v-for="item in letters" :key="item">{{item}}</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
letters: ['A', 'B', 'C', 'D','E']
}
})
</script>
</body>
</html>
4、那些数组的方法是响应式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="item in letters" :key="item">{{item}}</li>
</ul>
<button @click="btnClick">按钮</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
letters: ['A', 'B', 'C', 'E']
},
methods: {
btnClick() {
// 1、push方法
// this.letters.push('abc')
// this.letters.push('abc','def')
// 2、pop方法: 删除数组最后一个元素
// this.letters.pop()
// 3、shift方法: 删除数组中第一个元素
// this.letters.shift()
// 4、unshift方法: 在数组最前面添加元素
// this.letters.unshift('abc')
// this.letters.unshift('abc','def')
// 5、splice作用:
// 删除元素:第二个参数传入删除几个元素(如果没有,就删除到最后)
// this.letters.splice(2) //第二个元素删除到最后(不包括第二个元素)
// this.letters.splice(1,2) //从第一个元素开始删除2个元素
// 替换元素:第二个参数传入我们要替换几个元素,后面是用于替换前面的元素
// this.letters.splice(1,3,'x','y','z','l')
// 插入元素:第一个参数表示那个位置插入,第二个参数必须为0,后面跟要插入的元素
// this.letters.splice(1, 0,'x','y','z','l')
// 6、sort排序
// this.letters.sort()
// 7、reverse反转
// this.letters.reverse()
// 8、通过vue set
Vue.set(this.letters,0,'bbbb')
}
}
})
</script>
</body>
</html>
五、书籍购物车案例
1、目录结构
2、index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="app">
<div v-if="books.length">
<table>
<thead>
<th></th>
<th>书籍名称</th>
<th>出版日期</th>
<th>价格</th>
<th>购买数量</th>
<th>操作</th>
</thead>
<tbody>
<tr v-for="(item,index) in books">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.date}}</td>
<!--<td>{{getFinalPrice(item.price)}}</td>-->
<td>{{item.price | showPrice}}</td>
<td>
<button @click="decrement(index)" v-bind:disabled="item.count <= 1">-</button>
{{item.count}}
<button @click="increment(index)">+</button>
</td>
<td>
<button @click="removeHandle(index)">移除</button>
</td>
</tr>
</tbody>
</table>
<h2>总价格:{{totalPrice | showPrice}}</h2>
</div>
<h2 v-else> 购物车为空</h2>
</div>
<script src="../js/vue.js"></script>
<script src="main.js"></script>
</body>
</html>
3、main.js
const app = new Vue({
el: '#app',
data: {
books: [
{
id: 1,
name: '<<UNIX编程艺术>>',
date: '2006-2',
price: 59.00,
count: 1
},
{
id: 2,
name: '<<编程珠玑>>',
date: '2008-10',
price: 39.00,
count: 1
}
]
},
methods: {
// getFinalPrice(price) {
// return '¥' + price.toFixed(2)
// }
increment(index) {
this.books[index].count++
},
decrement(index) {
this.books[index].count--
},
removeHandle(index) {
this.books.splice(index,1)
}
},
computed: {
totalPrice() {
// 1、普通for循环
// let totalPrice = 0;
// for (let i =0; i< this.books.length; i++){
// totalPrice += this.books[i].price * this.books[i].count
// }
// return totalPrice
// 2、for(let i in this.books)
// let totalPrice = 0;
// for (let i in this.books) {
// totalPrice += this.books[i].price * this.books[i].count
// }
// return totalPrice
// 3、for(let i of this.books)
let totalPrice = 0;
for (let item of this.books) {
totalPrice += item.price * item.count
}
return totalPrice
}
},
// 过滤器
filters: {
showPrice(price) {
return '¥' + price.toFixed(2)
}
}
})
4、style.css
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: #f7f7f7;
color: #5c6b77;
font-weight: 600;
}
5、结果
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/b1028af092f6cf9ce058ef8e01d832f0.png)
六、高阶函数
1、filter函数
回调函数返回布尔值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1>{{message}}</h1>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'hello,Vue'
}
});
const nums = [1,30,140,120,5,40,200];
let newNums = nums.filter(function (n) {
return n < 100
});
console.log(newNums)
</script>
</body>
</html>
2、map函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1>{{message}}</h1>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'hello,Vue'
}
});
const nums = [1,30,140,120,5,40,200];
let newNums = nums.map(function (t) {
return t*2
});
console.log(newNums)
</script>
</body>
</html>
3、reduce函数
对数组中的所有内容进行汇总
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1>{{message}}</h1>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'hello,Vue'
}
});
const nums = [1,30,140,120,5,40,200];
let total = nums.reduce(function (p1, n) {
return p1 + n
}, 0); //0为初始值
console.log(total)
</script>
</body>
</html>
4、练习
函数式编程
1、方式一
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1>{{message}}</h1>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'hello,Vue'
}
});
const nums = [1,30,140,120,5,40,200];
let total = nums.filter(function (t) {
return t < 100
}).map(function (t) {
return t * 2
}).reduce(function (p1,n) {
return p1 + n
},0)
console.log(total)
</script>
</body>
</html>
2、方式二(简写)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1>{{message}}</h1>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'hello,Vue'
}
});
const nums = [1,30,140,120,5,40,200];
let total =nums.filter(n => n < 100).map(n => n * 2).reduce((pre,n) => pre + n)
console.log(total)
</script>
</body>
</html>