Vue指令之表单指令、斗篷指令、条件指令、循环指令、综合应用案例
Vue指令
表单指令
语法:v-model = "变量",v-model绑定的变量控制的是表单元素的value值。
普通表单元素:用v-model直接绑定变量控制value值。
单选框:以name进行分组,绑定的值为单选框的value值。
单一复选框:v-model绑定的值为true或false。
多个复选框:v-model绑定的值为存储value的数组。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>表单指令</title>
</head>
<body>
<div id="app">
<form action="">
<!--属性指令:v-model="变量",v-model绑定的变量控制的是表单元素的value值 -->
<!--普通表单元素,用v-model直接绑定变量控制value值-->
<input type="text" v-model="v1">
<input type="text" v-model="v1">
<textarea name="" id="" cols="30" rows="10" v-model="v1"></textarea>
<p>{{ v1 }}</p>
<hr>
<!--单一复选框-->
同意:
<input type="checkbox" name="agree" v-model="v2">
<hr>
<!--多个复选框-->
男:<input type="checkbox" name="hobbies" value="male" v-model="v3">
女:<input type="checkbox" name="hobbies" value="female" v-model="v3">
哇塞:<input type="checkbox" name="hobbies" value="wow" v-model="v3">
<p>{{ v3 }}</p>
<hr>
<!--单选框-->
中午吃啥:<br>
肉肉:<input name="food" type="radio" value="rourou" v-model="v4">
饭饭:<input name="food" type="radio" value="fanfan" v-model="v4">
<p>{{ v4 }}</p>
<hr>
<button type="submit">提交</button>
</form>
</div>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
v1: '',
v2: false, // false
v3: ['male', 'wow'],
v4: 'rourou',
}
})
</script>
</html>
斗篷指令
用来避免页面闪烁,先加载vue环境,有了vue环境后,这个v-cloak属性就被取消了
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>斗篷指令</title>
<style>
[v-cloak] { /*属性选择器*/
display: none;
}
</style>
</head>
<body>
<div id="app" v-cloak>
<p>{{ msg }}</p>
<p>{{ msg }}</p>
<p>{{ msg }}</p>
</div>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
msg: 12345
}
})
</script>
</html>
条件指令
条件指令:
- v-if="true|false":为真时显示;为假时,在页面上不渲染,可以隐藏标签中的信息
- v-show="true|false":为真时显示;为假时,在页面中用display:none渲染,虽然没显示,但是仍在页面结构中。
v-if 是一个家族:
- v-if
- v-else-if
- v-else
上分支成立,下分支会被屏蔽;else分支只有在所有上分支都为假时显示,且不需要条件。
条件指令案例(重点)
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>条件指令案例</title>
<style>
.box {
400px;
height: 200px;
}
.r { background-color: red }
.y { background-color: yellow }
.g { background-color: green }
.action {
background-color: pink;
}
</style>
</head>
<body>
<div id="app">
<p>
<button @click="changeC('red')" :class="{action: c === 'red'}">红</button>
<!--<button @click="changeC('red')" :class="c === 'red'? 'action': ''">红</button>-->
<button @click="changeC('yellow')" :class="{action: c === 'yellow'}">黄</button>
<button @click="changeC('green')" :class="{action: c === 'green'}">绿</button>
</p>
<div class="wrap">
<div class="box r" v-if="c === 'red'"></div>
<div class="box y" v-else-if="c === 'yellow'"></div>
<div class="box g" v-else></div>
</div>
</div>
</body>
<script src="js/vue.js"></script>
<script>
// sessionStorage的生命周期与页面标签绑定,当标签页被关闭,数据库被清空
// localStorage是前台永久数据库
// sessionStorage.name = '123';
// localStorage.name = 'xyz';
// localStorage.clear();
new Vue({
el: '#app',
data: {
// 页面重新刷新加载,可以从数据库中获取缓存,如果没有,再取默认值
// c: 'red',
c: localStorage.c ? localStorage.c : 'red',
},
methods: {
changeC(color) {
this.c = color;
// 每一次改变c的值,将值同步到前台数据库
localStorage.c = color; // 存
}
}
})
</script>
</html>
循环指令
v-for="" 语法:v-for="成员 in 容器"
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<!--循环指令:
v-for=""
语法:
v-for="成员 in 容器"
-->
<!--1、字符串循环渲染: 可以只遍历值,也可以遍历值与索引-->
<p>
<span v-for="v in title">{{ v }}</span>
</p>
<p>
<span v-for="(v, i) in title">
<span v-if="i != 0"> | </span>
{{ v }}
</span>
</p>
<!--2、数组循环渲染: 可以只遍历值,也可以遍历值与索引,接收两个值时,第一个为元素值,第二个为元素索引-->
<div>
<p v-for="(v, i) in arr">第{{ i }}元素:{{ v }}</p>
</div>
<!--3、对象循环渲染: 可以只遍历值,也可以遍历值与键,还可以遍历值、键与索引,接收三个值时,第一个为元素值,第二个为元素键,第三个为元素索引-->
<div>
<p v-for="v in people">{{ v }}</p>
</div>
<div>
<p v-for="(v, k) in people">{{ k }}:{{ v }}</p>
</div>
<div>
<p v-for="(v, k, i) in people">{{ i }}-{{ k }}:{{ v }}</p>
</div>
<br>
<div>
<!--遍历的嵌套-->
<div v-for="(stu, i) in stus">
<hr v-if="i != 0"> <!--索引不为0的元素下面有下划线-->
<p v-for="(v, k) in stu">{{ k }}:{{ v }}</p>
</div>
</div>
</div>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
title: '循环指令',
arr: [1, 4, 2, 5, 3],
people: {
name: '兔子',
color: '粉白',
price: 6.66,
},
stus: [
{
name: "Bob",
age: 18
},
{
name: "Tom",
age: 17
},
{
name: "Jerry",
age: 19
}
]
}
})
</script>
</html>
循环指令案例
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<input type="text" v-model="msg">
<button @click="send_comment">留言</button>
<ul>
<li v-for="(v, i) in comments" @click="deleteMsg(i)">{{ v }}</li>
</ul>
</div>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
msg: '',
comments: []
},
methods: {
send_comment() {
// 数组的增
// push pop unshift shift splice
// this.comments.unshift(this.msg);
// this.comments.splice(0,0,0);
if (this.msg) {
this.comments.push(this.msg); // 留言
this.msg = ''; // 留言后清空输入框
}
},
deleteMsg(index) {
this.comments.splice(index, 1);
}
}
})
</script>
<script>
// 数组操作万能方法,可以完成增删改
let arr = [1, 2, 3];
// 参数:开始索引,操作长度,操作的结果们
arr.splice(2, 0, 100); // 在3前面加个100
arr.splice(1, 1); // 删除2
console.log(arr);
</script>
</html>
综合应用案例
现有以下成绩单数据
scores = [
{ name: 'Bob', math: 97, chinese: 89, english: 67 },
{ name: 'Tom', math: 67, chinese: 52, english: 98 },
{ name: 'Jerry', math: 72, chinese: 87, english: 89 },
{ name: 'Ben', math: 92, chinese: 87, english: 59 },
{ name: 'Chan', math: 47, chinese: 85, english: 92 },
]
用table表格标签渲染以上数据,表格第一列是学生总分排序,最后一列是学生总分;
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<table border="1" width="400" rules="all" style="margin: auto">
<tr>
<th>排名</th>
<th>姓名</th>
<th>数学</th>
<th>语文</th>
<th>英语</th>
<th>总分</th>
</tr>
<tr v-for="(stu,i) in scores">
<td>{{ i + 1 }}</td>
<td v-for="v in stu">{{ v }}</td>
</tr>
</table>
</div>
</body>
<script src="js/vue.js"></script>
<script>
let scores = [
{name: 'Bob', math: 97, chinese: 89, english: 67},
{name: 'Tom', math: 67, chinese: 52, english: 98},
{name: 'Jerry', math: 72, chinese: 87, english: 89},
{name: 'Ben', math: 92, chinese: 87, english: 59},
{name: 'Chan', math: 47, chinese: 85, english: 92},
];
let total_scores = [];
for (stu of scores) {
stu.total = stu.math + stu.chinese + stu.english;
total_scores.push(stu);
}
// 冒泡排序
for(let i = 0; i < total_scores.length - 1; i++) {
for(let j = 0; j < total_scores.length - 1 - i; j++) {
if (total_scores[j].total < total_scores[j+1].total) {
let t = total_scores[j];
total_scores[j] = total_scores[j+1];
total_scores[j+1] = t;
}
}
}
new Vue({
el: '#app',
data: {
scores: total_scores,
}
});
// 冒泡排序举例
let arr = [1, 4, 2, 5, 3];
for (let i=0; i < 5 - 1; i++) {
for (let j=0; j < 5 - 1 - i; j++) {
if (arr[j] > arr[j+1]) {
// arr[j] ^= arr[j+1];
// arr[j+1] ^= arr[j];
// arr[j] ^= arr[j+1];
let t = arr[j];
arr[j] = arr[j+1];
arr[j+1] = t;
}
}
}
</script>
</html>
还是采用上方相同的数据,采用相同的渲染规则,只渲染所有科目都及格了的学生。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<table border="1" width="400" rules="all" style="margin: auto">
<tr>
<th>排名</th>
<th>姓名</th>
<th>数学</th>
<th>语文</th>
<th>英语</th>
<th>总分</th>
</tr>
<tr v-for="(stu,i) in scores" v-if="stu.math>60&&stu.chinese>60&&stu.english>60"> <!-- 加个条件指令判断分数都大于60 -->
<td>{{ i + 1 }}</td>
<td v-for="v in stu">{{ v }}</td>
</tr>
</table>
</div>
</body>
<script src="js/vue.js"></script>
<script>
let scores = [
{name: 'Bob', math: 97, chinese: 89, english: 67},
{name: 'Tom', math: 67, chinese: 52, english: 98},
{name: 'Jerry', math: 72, chinese: 87, english: 89},
{name: 'Ben', math: 92, chinese: 87, english: 59},
{name: 'Chan', math: 47, chinese: 85, english: 92},
];
let total_scores = [];
for (stu of scores) {
stu.total = stu.math + stu.chinese + stu.english;
total_scores.push(stu);
}
for(let i = 0; i < total_scores.length - 1; i++) {
for(let j = 0; j < total_scores.length - 1 - i; j++) {
if (total_scores[j].total < total_scores[j+1].total) {
let t = total_scores[j];
total_scores[j] = total_scores[j+1];
total_scores[j+1] = t;
}
}
}
new Vue({
el: '#app',
data: {
scores: total_scores,
},
});
</script>
</html>
还是采用上方相同的数据,添加筛选规则:
i)有三个按钮:语文、数学、外语,点击谁谁高亮,且当前筛选规则采用哪门学科
ii)两个输入框,【】~【】,前面天最小分数,后面填最大分数,全部设置完毕后,表格的数据会被更新只渲染满足所有条件的结果
举例:点击语文,输入【86】~【87】,那就只会渲染Jerry和Ben两条数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>作业1</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script>
<style>
div{
text-align: center;
}
th{
text-align: center;
}
.action{
background-color: pink;
}
</style>
</head>
<body>
<div id="app">
<h2>学生成绩单</h2>
<p style="margin: 10px auto; 400px;">
<button :class="{action: rule === 'chinese'}" @click="clickAction('chinese')">语文</button>
<button :class="{action: rule === 'math'}" @click="clickAction('math')">数学</button>
<button :class="{action: rule === 'english'}" @click="clickAction('english')">英语</button>
<input type="number" min="1" max="100" v-model="min">
~
<input type="number" min="1" max="100" v-model="max">
</p>
<table class="table table-bordered" >
<thead>
<tr>
<th>名次</th>
<th v-for="(v, k, i) in scores[0]">{{ k }}</th>
<th>total_points</th>
</tr>
</thead>
<tbody v-if="rule === 'chinese'">
<tr v-for="(stu, i) in scores" v-if="(min && max && stu.chinese >= +min && stu.chinese <= +max) || (!min || !max)">
<td>{{ i+1 }}</td>
<td v-for="v in stu">{{ v }}</td>
<td>{{ stu['math']+stu['chinese']+stu['english'] }}</td>
</tr>
</tbody>
<tbody v-else-if="rule === 'math'">
<tr v-for="(stu, i) in scores" v-if="(min && max && stu.math >= +min && stu.math <= +max) || (!min || !max)">
<td>{{ i+1 }}</td>
<td v-for="v in stu">{{ v }}</td>
<td>{{ stu['math']+stu['chinese']+stu['english'] }}</td>
</tr>
</tbody>
<tbody v-else-if="rule === 'english'">
<tr v-for="(stu, i) in scores" v-if="(min && max && stu.english >= +min && stu.english <= +max) || (!min || !max)">
<td>{{ i+1 }}</td>
<td v-for="v in stu">{{ v }}</td>
<td>{{ stu['math']+stu['chinese']+stu['english'] }}</td>
</tr>
</tbody>
<tbody v-else=>
<tr v-for="(stu, i) in scores">
<td>{{ i+1 }}</td>
<td v-for="v in stu">{{ v }}</td>
<td>{{ stu['math']+stu['chinese']+stu['english'] }}</td>
</tr>
</tbody>
</table>
<span style="display: none">{{ range }}</span>
</div>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
scores: [
{ name: 'Bob', math: 97, chinese: 89, english: 67 },
{ name: 'Tom', math: 67, chinese: 52, english: 98 },
{ name: 'Jerry', math: 72, chinese: 87, english: 89 },
{ name: 'Ben', math: 92, chinese: 87, english: 59 },
{ name: 'Chan', math: 47, chinese: 85, english: 92 },
],
rule: '',
min: '',
max: '',
},
computed: {
range: function () {
return this.scores.sort((a, b) => (a.math+a.chinese+a.english) - (b.math+b.chinese+b.english)).reverse() // 还可以用这种匿名函数的方法对表格数据按总分进行排序
}
},
methods: {
clickAction(rule) {
this.rule = rule;
}
}
});
</script>
</html>