文章目录
指令修饰符
①按键修饰符
@keyup.enter -> 键盘回车监听
②v-model修饰符
v-model.trim -> 去除首尾空格
v-model.number -> 转数字
③事件修饰符
@事件名.stop -> 阻止冒泡
@事件名.prevent -> 阻止默认行为
v-bind操作CSS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<style>
.box {
width: 100px;
height: 100px;
border: 1px solid black;
text-align: center;
}
.bgColor {
background-color: aquamarine;
}
.bigger {
width: 200px;
height: 200px;
}
</style>
</head>
<body>
<!-- 适用场景:一个类名 来回切换 -->
<!-- <div id="box" class="box" :class="{bgColor:false,bigger:true}"> -->
<!-- 适用场景:批量添加或删除类 -->
<div id="box" class="box" :class="['bgColor','bigger']">
Nice day!
</div>
<!-- 操作style <div class="box" :style="{CSS属性名1:'CSS属性值',CSS属性名2:'CSS属性值'}"></div> -->
<script>
const app = new Vue({
el: "#box",
data: {
}
});
</script>
</body>
</html>
案例-京东秒杀Tab导航高亮
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<style>
li {
list-style: none;
display: inline-block;
width: 120px;
height: 50px;
margin-right: 20px;
text-align: center;
}
a {
text-decoration: none;
color: black;
font-size: 25px;
line-height: 50px;
}
.active {
background-color: red;
}
</style>
</head>
<body>
<div id="nav">
<ul>
<li v-for="(item,index) in list" @click="activeIndex=index">
<a href="#" :class="{active:(index===activeIndex)}">{{item.name}}</a>
</li>
</ul>
<hr>
</div>
<script>
const app = new Vue({
el: "#nav",
data: {
list: [
{ id: 1, name: '京东秒杀' },
{ id: 2, name: '每日特价' },
{ id: 3, name: '品类秒杀' }
],
activeIndex: 0
}
});
</script>
</body>
</html>
案例-小黑学习网(v-model应用于其他表单元素)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<style>
#app {
width: 640px;
height: 480px;
background-color: aquamarine;
margin: 100px auto;
}
</style>
</head>
<body>
<div id="app">
<h1>小黑学习网</h1>
姓名:
<input type="text" v-model="username">
<br><br>
是否单身:
<input type="checkbox" name="" id="" v-model="isSingle">
<br><br>
性别:
<input type="radio" name="sex" value="1" v-model="gender">♂男
<input type="radio" name="sex" value="0" v-model="gender">♀女
<br><br>
所在城市:
<select name="" id="" v-model="city">
<option value="北京">北京</option>
<option value="上海">上海</option>
<option value="成都">成都</option>
<option value="南京">南京</option>
</select>
<br><br>
自我描述:
<textarea name="" id="" cols="30" rows="10" style="resize: none;" v-model="desc"></textarea>
<br><br>
<button @click="sign">立即注册</button>
<br><br>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
username: '',
isSingle: false,
gender: '1',
city: '北京',
desc: ''
},
methods: {
sign() {
if (this.username === '' || this.desc === '') {
alert('请输入完整信息!!!');
return;
}
alert(
'姓名:' + this.username + '\n' +
'性别:' + (this.gender === '1' ? '男' : '女') + '\n' +
'是否单身:' + (this.isSingle ? '是' : '否') + '\n' +
'所在城市:' + this.city + '\n' +
'自我介绍:' + this.desc + '\n' +
'注册成功!!!'
);
}
}
});
</script>
</body>
</html>
computed计算属性-简略写法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
<h1>小黑的礼物清单</h1>
<table border="1" width="300">
<tr>
<th>名字</th>
<th>数量</th>
</tr>
<tr v-for="(item,index) in list" :key="item.id">
<td>{{item.name}}</td>
<td>{{item.num}}</td>
</tr>
</table>
<p>礼物总数:{{totalCount}}个</p>
</div>
<script>
const app = new Vue({
el: "#box",
data: {
list: [
{ id: 1, name: "蓝球", num: 1 },
{ id: 2, name: "玩具", num: 2 },
{ id: 3, name: "铅笔", num: 5 },
]
},
computed: {
totalCount() {
let total = this.list.reduce((sum, item) => sum + item.num, 0);
return total;
}
}
});
</script>
</body>
</html>
computed计算属性和methods方法的区别
computed 计算属性:
作用:封装了一段对于数据的处理,求得一个结果。
语法:
① 写在 computed 配置项中
② 作为属性,直接使用 → this.计算属性 {{ 计算属性 }}
缓存特性(提升性能):
计算属性会对计算出来的结果缓存,再次使用直接读取缓存,
依赖项变化了,会自动重新计算 → 并再次缓存
methods 方法:
作用:给实例提供一个方法,调用以处理业务逻辑。
语法:
① 写在 methods 配置项中
② 作为方法,需要调用 → this.方法名( ) {{ 方法名() }} @事件名=“方法名”
computed计算属性-完整写法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
姓:<input type="text" v-model="firstName">+
名:<input type="text" v-model="lastName">=
<span>{{fullName}}</span>
<br><br>
<button @click="changeName">改名卡</button>
</div>
<script>
const app = new Vue({
el: "#box",
data: {
firstName: '刘',
lastName: '备'
},
methods: {
changeName() {
this.fullName = "张飞";
console.log("改名");
}
},
computed: {
// 简写 -> 获取,没有配置设置的逻辑
// fullName() {
// return this.firstName + this.lastName;
// }
// 完整写法 -> 获取 + 设置
fullName: {
get() {
return this.firstName + this.lastName;
},
set(value) { //被修改赋值时执行
this.firstName = value.slice(0, 1);
this.lastName = value.slice(1);
}
}
}
});
</script>
</body>
</html>
成绩案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<style>
.red {
color: red;
}
</style>
</head>
<body>
<div id="box">
<div>
<table border="1" width="400">
<tr>
<th>编号</th>
<th>科目</th>
<th>成绩</th>
<th>操作</th>
</tr>
<tbody v-if="list.length>0">
<tr v-for="(item,index) in list" :key="item.id">
<td>{{index+1}}</td>
<td>{{item.subject}}</td>
<td :class="{red:item.score<60}">{{item.score}}</td>
<td><button @click="Remove(item.id)">删除</button></td>
</tr>
</tbody>
<tbody v-else>
<td colspan="4" style="text-align: center;">暂无数据</td>
</tbody>
</table>
<span>总分:{{Total}}</span>
<span>平均分:{{Average}}</span>
</div>
<div>
科目:<input type="text" v-model.trim="subject">
分数:<input type="text" v-model.number="score">
<button @click="Add">添加</button>
</div>
</div>
<script>
const app = new Vue({
el: "#box",
data: {
list: [
{ id: 1, subject: '语文', score: 20 },
{ id: 7, subject: '数学', score: 99 },
{ id: 12, subject: '英语', score: 70 },
],
subject: '',
score: ''
},
methods: {
Remove(id) {
this.list = this.list.filter(item => item.id != id);
},
Add() {
if (!this.subject) {
alert("请输入科目!");
return;
}
if (typeof this.score !== 'number') {
alert('请输入正确的成绩!');
return;
}
this.list.unshift({ id: +new Date(), subject: this.subject, score: this.score });
this.subject = '';
this.score = '';
}
},
computed: {
Total() {
return this.list.reduce((sum, item) => sum + item.score, 0);
},
Average() {
if (this.list.length === 0)
return 0;
return (this.Total / this.list.length).toFixed(2);
}
}
});
</script>
</body>
</html>
watch侦听器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="box">
<input type="text" name="" id="" v-model="obj.words">
</div>
<script>
const app = new Vue({
el: "#box",
data: {
// words: ''
obj: {
words: ""
}
},
watch: {
// words(newValue, oldValue) { // oldValue 可省略
// console.log('变化了', newValue, oldValue);
// }
'obj.words'(newValue) {
console.log('变化了', newValue);
},
// // 完整写法
// obj: {
// deep: true, //深度监视
// immediate: true, //立刻执行,一进入页面就执行一次
// handle(newValue) { //数据修改时触发
// }
// }
}
});
</script>
</body>
</html>
案例-水果购物车
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<style>
td {
text-align: center;
}
</style>
</head>
<body>
<div id="box">
<table border="1" width="1000">
<thead>
<tr>
<th>选中</th>
<th>水果</th>
<th>单价</th>
<th>个数</th>
<th>小计</th>
<th>操作</th>
</tr>
</thead>
<tbody v-if="list.length===0">
<td colspan="6">空空如也</td>
</tbody>
<tbody v-else v-for="(item,index) in list" :key="item.id">
<tr>
<td><input type="checkbox" v-model="item.isChecked"></td>
<td>{{item.name}}</td>
<td>{{item.price}}</td>
<td>
<button @click="item.num--" :disabled="item.num<=1">-</button>
{{item.num}}
<button @click="item.num++">+</button>
</td>
<td>{{item.price*item.num}}</td>
<td><a href="https://www.baidu.com" @click.prevent="del(item.id)">删除</a></td>
</tr>
</tbody>
<tfoot>
<td><input type="checkbox" v-model="isAll">全选</td>
<td colspan="3"></td>
<td>总价:¥{{totalPrice}}</td>
<td><button>结算{{totalCount}}</button></td>
</tfoot>
</table>
</div>
<script>
const defaultArr = [
{ id: 1, name: '火龙果', isChecked: true, num: 2, price: 3 },
{ id: 2, name: '苹果', isChecked: false, num: 8, price: 7 },
{ id: 3, name: '香蕉', isChecked: false, num: 6, price: 5 },
{ id: 4, name: '葡萄', isChecked: false, num: 3, price: 10 },
{ id: 5, name: '香梨', isChecked: false, num: 9, price: 4 },
];
const app = new Vue({
el: "#box",
data: {
list: JSON.parse(localStorage.getItem('list')) || defaultArr
},
methods: {
del(id) {
this.list = this.list.filter(item => item.id != id);
}
},
computed: {
// isAll() {
// return this.list.every(item => item.isChecked === true);
// }
isAll: {
get() {
return this.list.every(item => item.isChecked === true);
},
set(value) {
this.list.forEach(function (item) {
item.isChecked = value;
});
}
},
totalCount() {
return this.list.reduce((sum, item) => {
if (item.isChecked) {
return sum + item.num;
}
else {
return sum;
}
}, 0);
},
totalPrice() {
return this.list.reduce((sum, item) => {
if (item.isChecked) {
return sum + (item.num * item.price);
}
else {
return sum;
}
}, 0);
}
},
watch: {
list: {
deep: true,
handler(newValue) {
localStorage.setItem('list', JSON.stringify(newValue)); // 存到本地
}
}
}
});
</script>
</body>
</html>