Vue:v-for,v-if, key,HBuilder和VScode实现用按钮来分类筛选表格内容【诗书画唱】


目录:
例子1:HBuilder中用v-for等等拼接出一个表格(该表有排名,姓名,语文,数学,英语列等等)
例子2: 在Hbuilder中拼接出科目表格(该表有排名,姓名,语文,数学,英语列等等),并且可以进行分类筛选:创建语文,数学,英语3个按钮和2个填写分数范围type="number"的input框。点击其中一个科目按钮(点击后该按钮会变橘色),在输入分数后,就只显示在被点击按钮的科目的分数的范围之内的学生的列的内容。
例子3:在Vscode中实现例子1
在Vscode中要在score前声明let(不然在Vscode中会报XXX未定义之类的错误,个人认为Vscode中的语法会比在HBuilder中更严格,当然我相比下,更喜欢Vscode,因为界面好看,提示也多,一些好的插件功能强大,有时又自动修复bug功能,而且更方便下载。当然我也很喜欢HBuilder)
Vscode中,在使用了v-for="(score,i) in scores"后就必须写 v-bind:key="i",不然会报错
Avoid using non-primitive value as key, use string/number value instead.
Vscode编辑器中使用v-for的报错解决方法
Elements in iteration expect to have 'v-bind:key' directives
Table1.vue
index.js
例子4:在Vscode中实现例子2
Vscode中v-for和v-if不可以放一起,那么本来的<tr v-for="(score,i) in scores" v-bind:key="i" v-if="score.math>=min && score.math<=max ||(!min||!max)">就被我改写成<tbody v-for="(score,i) in scores" v-bind:key="i"><tr v-if="score.math>=min && score.math<=max ||(!min||!max)">
<tbody > 套<tbody>时,<th>和<td>的宽度不同时,用CSS样式统一<th/>和</td>的宽度
Table2.vue
index.js
科普(推荐好文):
https://www.cnblogs.com/liyanyan665/p/11192635.html
Vue - ElementUI中循环渲染表格,控制字段的显示与隐藏 v-if与v-for同时使用
https://mp.weixin.qq.com/s?src=11×tamp=1621139141&ver=3071&signature=apMJgWY*vlL32v18XPBSkkT5s3Nip3huntQKliosDoSE5L6N*HlYXZgSHaQAoH6311YlNJfolCOSYBtdP2Hd0IgT9NybtY0hU0oS6KW1bsOGSgxCtK1kiscMV-2P0D6d&new=1
https://zhuanlan.zhihu.com/p/141238031
https://blog.csdn.net/weixin_44583625/article/details/93162611

例子1:HBuilder中用v-for等等拼接出一个表格(该表有排名,姓名,语文,数学,英语列等等)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<table border="1" style="margin: auto" rules="all">
<tr>
<th>排名</th>
<th>姓名</th>
<th>数学</th>
<th>语文</th>
<th>英语</th>
<th>总分</th>
</tr>
<!-- 1题答案 -->
<tr v-for="(score,i) in scores">
<td>{{i+1}}</td>
<td v-for="v in score">{{v}}</td>
</tr>
<!-- 2题答案 -->
<!--<tr v-for="(score,i) in scores" v-if="score.math>=60&&score.chinese>=60&&score.english>=60">
<td>{{i+1}}</td>
<td v-for="v in score">{{v}}</td>
</tr>-->
</table>
</div>
</body>
<script srcc="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},
];
//这里需要注意一点:for in遍历的是取值关键字而for of遍历的是值
//添加总分
for (score of scores) {
score.total = score.math + score.chinese + score.english
}
//按照总分排序
//这里使用的是冒泡算法
for (let i = 0; i < scores.length - 1; i++) {
for (let j = 0; j < scores.length - 1 - i; j++) {
if (scores[j].total < scores[j + 1].total) {
let temp = scores[j];
scores[j] = scores[j + 1];
scores[j + 1] = temp
}
}
}
console.log(scores);
new Vue({
el: '#app',
data: {
//属性名与值为变量名的变量名相同的时候,可以简写省略值
scores,
}
})
</script>
</html>


例子2: 在Hbuilder中拼接出科目表格(该表有排名,姓名,语文,数学,英语列等等),并且可以进行分类筛选:创建语文,数学,英语3个按钮和2个填写分数范围type="number"的input框。点击其中一个科目按钮(点击后该按钮会变橘色),在输入分数后,就只显示在被点击按钮的科目的分数的范围之内的学生的列的内容。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
.active{
background-color: chocolate;
}
</style>
</head>
<body>
<!-- 采用相同的数据,添加筛选条件:
1、有三个按钮:数学,语文、外语,点击谁高亮,
2、两个输入框,【】~【】,前面小的分数,后面大分数,全部设置完毕,按照要求筛选出对应的信息 -->
<div id="app">
<div style="width: 400px;margin: 20px auto;">
<button @click="subject='math'" :class="{active: subject==='math'}">数学</button>
<button @click="subject='chinese'" :class="{active: subject==='chinese'}">语文</button>
<button @click="subject='english'" :class="{active: subject==='english'}">英语</button>
<input type="number" min="0" max="100" v-model="min">
~
<input type="number" min="0" max="100" v-model="max">
</div>
<table border="1" style="margin: auto" rules="all">
<tr>
<th>排名</th>
<th>姓名</th>
<th>数学</th>
<th>语文</th>
<th>英语</th>
<th>总分</th>
</tr>
<tbody v-if="subject==='math'">
<tr v-for="(score,i) in scores" v-if="score.math>=min && score.math<=max ||(!min||!max)">
<td>{{i+1}}</td>
<td v-for="v in score">{{v}}</td>
</tr>
</tbody>
<tbody v-else-if="subject==='chinese'">
<tr v-for="(score,i) in scores" v-if="score.chinese>=min && score.chinese<=max ||(!min||!max)">
<td>{{i+1}}</td>
<td v-for="v in score">{{v}}</td>
</tr>
</tbody>
<tbody v-else-if="subject==='english'">
<tr v-for="(score,i) in scores" v-if="score.english>=min && score.english<=max ||(!min||!max)">
<td>{{i+1}}</td>
<td v-for="v in score">{{v}}</td>
</tr>
</tbody>
<tbody v-else=>
<tr v-for="(score,i) in scores">
<td>{{i+1}}</td>
<td v-for="v in score">{{v}}</td>
</tr>
</tbody>
</table>
</div>
</body>
<script srcc="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},
];
//这里需要注意一点:for in遍历的是取值关键字而for of遍历的是值
//添加总分
for (score of scores) {
score.total = score.math + score.chinese + score.english
}
//按照总分排序
//这里使用的是冒泡算法
for (let i = 0; i < scores.length - 1; i++) {
for (let j = 0; j < scores.length - 1 - i; j++) {
if (scores[j].total < scores[j + 1].total) {
let temp = scores[j];
scores[j] = scores[j + 1];
scores[j + 1] = temp
}
}
}
console.log(scores);
new Vue({
el: '#app',
data: {
//属性名与值为变量名的变量名相同的时候,可以简写省略值
scores,
min:'',
max:'',
subject:'',
}
})
</script>
</html>


例子3:在Vscode中实现例子1
在Vscode中要在score前声明let(不然在Vscode中会报XXX未定义之类的错误,个人认为Vscode中的语法会比在HBuilder中更严格,当然我相比下,更喜欢Vscode,因为界面好看,提示也多,一些好的插件功能强大,有时又自动修复bug功能,而且更方便下载。当然我也很喜欢HBuilder)

Vscode中,在使用了v-for="(score,i) in scores"后就必须写 v-bind:key="i",不然会报错

Avoid using non-primitive value as key, use string/number value instead.

Vscode编辑器中使用v-for的报错解决方法
Elements in iteration expect to have 'v-bind:key' directives
个人倾向于用方法1

Table1.vue
<template>
<div id="app">
<table border="1" style="margin: auto" rules="all">
<tr>
<th>排名</th>
<th>姓名</th>
<th>数学</th>
<th>语文</th>
<th>英语</th>
<th>总分</th>
</tr>
<!-- 1题答案 -->
<tr v-for="(score,i) in scores" v-bind:key="i" >
<td>{{i+1}}</td>
<td v-for="v in score" v-bind:key="v">{{v}}</td>
</tr>
<!-- 2题答案 -->
<!--<tr v-for="(score,i) in scores" v-if="score.math>=60&&score.chinese>=60&&score.english>=60">
<td>{{i+1}}</td>
<td v-for="v in score">{{v}}</td>
</tr>-->
</table>
</div>
</template>
<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},
];
//这里需要注意一点:for in遍历的是取值关键字而for of遍历的是值
//添加总分(在Vscode中要在score前声明let)
for (let score of scores) {
score.total = score.math + score.chinese + score.english
}
//按照总分排序
//这里使用的是冒泡算法
for (let i = 0; i < scores.length - 1; i++) {
for (let j = 0; j < scores.length - 1 - i; j++) {
if (scores[j].total < scores[j + 1].total) {
let temp = scores[j];
scores[j] = scores[j + 1];
scores[j + 1] = temp
}
}
}
console.log(scores);
export default {
/*定义username和password等变量的部分 START(不写就会报
Property or method "username" is not defined
之类变量未定义的错误)*/
data() {
return {
scores,
};
},
/*定义username和password等变量的部分 END*/
// methods: {
// f: function () {
// console.log(this.username);
// console.log(this.password);
// console.log(this.username == "诗书画唱");
// console.log(this.password == "666666");
// if (this.username == "诗书画唱" && this.password == "666666") {
// this.$router.push({
// name: "My_login_success",
// params: {
// act: this.username,
// pwd: this.password,
// state: "登录成功!",
// },
// });
// } else if (this.username != "诗书画唱" || this.password != "666666") {
// alert("登录失败,请输入正确的用户名和密码!");
// // this.$router.push({
// // name: "My_login",
// // params: {
// // state: "登录失败,请输入正确的用户名和密码!"
// // },
// // });
// }
// },
// },
}
</script>

index.js

import Vue from 'vue'
import Router from 'vue-router'
//自己加入的必须加载和要使用组件的代码 START
import Table1 from '@/components/Table1'
//自己加入的必须加载和要使用组件的代码 END
Vue.use(Router)
export default new Router({
routes: [
//http://localhost:8080/#/Table1
{
path: '/Table1',
name: 'Table1',//路由跳转时使用
component: Table1//记得写加载要使用的这个组件的代码
}
,
//自己加的代码 END
]
})
//解决重复点击路由,界面跳转等时报错的代码 START
const originalPush = Router.prototype.push
Router.prototype.push = function push (location) {
return originalPush.call(this, location).catch(err => err)
}
//解决重复点击路由,界面跳转等时报错的代码 END



例子4:在Vscode中实现例子2
个人的解决思路(这个思路是经过我的思路修改后,去除尝试时错误等等的思路,自己总结出来的,可以用于很多的领域):
在可行的例子中修改成符合要求的可行例子(先在HBuilder中修改成符合要求的例子,后面转移到Vscode中实现。我在Vscode中实现的例子3的基础上,对照HBuilder中的“作业二.html”文件,一条一条地加上例子3相比“作业二.html”没有的代码。一部分,一部分地加代码,分别运行,每当新加的代码让例子3出错,那么可以锁定错在新加的代码,后面百度错误,解决,猜想等等。进行分层注释后更容易理解例子,发现错误,修改错误成功等等)


Vscode中v-for和v-if不可以放一起,那么本来的<tr v-for="(score,i) in scores" v-bind:key="i" v-if="score.math>=min && score.math<=max ||(!min||!max)">就被我改写成<tbody v-for="(score,i) in scores" v-bind:key="i"><tr v-if="score.math>=min && score.math<=max ||(!min||!max)">






Table2.vue

<style>
.active{
background-color: chocolate;
}
th{
width: 100px;
}
td{
width: 100px;
}
</style>
<template>
<div id="app">
<!-- 筛选部分 START -->
<div style="width: 400px;margin: 20px auto;">
<button @click="subject='math'" :class="{active: subject==='math'}">数学</button>
<button @click="subject='chinese'" :class="{active: subject==='chinese'}">语文</button>
<button @click="subject='english'" :class="{active: subject==='english'}">英语</button>
<input type="number" min="0" max="100" v-model="min">
<input type="number" min="0" max="100" v-model="max">
</div>
<!-- 筛选部分 END -->
<table border="1" style="margin: auto" rules="all">
<tbody >
<tbody>
<tr >
<th >排名</th>
<th >姓名</th>
<th >数学</th>
<th>语文</th>
<th>英语</th>
<th>总分</th>
</tr>
</tbody>
</tbody>
<!-- 1题答案 -->
<!-- 数学部分 START -->
<!-- <tbody v-if="subject==='math'">
<tr v-for="(score,i) in scores" v-bind:key="i" >
<td v-if="score.math>=min && score.math<=max ||(!min||!max)">{{i+1}}</td>
<td v-for="v in score" v-bind:key="v">{{v}}</td>
</tr>
</tbody> -->
<tbody v-if="subject==='math'">
<tbody v-for="(score,i) in scores" v-bind:key="i">
<tr v-if="score.math>=min && score.math<=max ||(!min||!max)">
<td >{{i+1}}</td>
<td v-for="v in score" v-bind:key="v" >{{v}}</td>
</tr>
</tbody>
</tbody>
<!-- 数学部分 END -->
<!-- 语文部分 START -->
<!-- <tbody v-else-if="subject==='chinese'">
<tr v-for="(score,i) in scores" v-bind:key="i" >
<td v-if="score.chinese>=min && score.chinese<=max ||(!min||!max)">{{i+1}}</td>
<td v-for="v in score" v-bind:key="v">{{v}}</td>
</tr>
</tbody> -->
<tbody v-else-if="subject==='chinese'">
<tbody v-for="(score,i) in scores" v-bind:key="i" >
<tr v-if="score.chinese>=min && score.chinese<=max ||(!min||!max)">
<td >{{i+1}}</td>
<td v-for="v in score" v-bind:key="v" >{{v}}</td>
</tr>
</tbody>
</tbody>
<!-- 语文部分 END -->
<!-- 英语部分 START -->
<!-- <tbody v-else-if="subject==='english'">
<tr v-for="(score,i) in scores" v-bind:key="i" >
<td v-if="score.english>=min && score.english<=max ||(!min||!max)">{{i+1}}</td>
<td v-for="v in score" v-bind:key="v">{{v}}</td>
</tr>
</tbody> -->
<tbody v-else-if="subject==='english'">
<tbody v-for="(score,i) in scores" v-bind:key="i">
<tr v-if="score.english>=min && score.english<=max ||(!min||!max)">
<td >{{i+1}}</td>
<td v-for="v in score" v-bind:key="v" >{{v}}</td>
</tr>
</tbody>
</tbody>
<!-- 英语部分 END -->
<!-- 什么按钮都不点 START -->
<tbody v-else>
<tbody>
<tr v-for="(score,i) in scores" v-bind:key="i" >
<td >{{i+1}}</td>
<td v-for="v in score" v-bind:key="v" >{{v}}</td>
</tr>
</tbody>
</tbody>
<!-- 什么按钮都不点 END -->
<!-- 2题答案 -->
<!--<tr v-for="(score,i) in scores" v-if="score.math>=60&&score.chinese>=60&&score.english>=60">
<td>{{i+1}}</td>
<td v-for="v in score">{{v}}</td>
</tr>-->
</table>
</div>
</template>
<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},
];
//这里需要注意一点:for in遍历的是取值关键字而for of遍历的是值
//添加总分(在Vscode中要在score前声明let)
for (let score of scores) {
score.total = score.math + score.chinese + score.english
}
//按照总分排序
//这里使用的是冒泡算法
for (let i = 0; i < scores.length - 1; i++) {
for (let j = 0; j < scores.length - 1 - i; j++) {
if (scores[j].total < scores[j + 1].total) {
let temp = scores[j];
scores[j] = scores[j + 1];
scores[j + 1] = temp
}
}
}
console.log(scores);
export default {
/*定义username和password等变量的部分 START(不写就会报
Property or method "username" is not defined
之类变量未定义的错误)*/
data() {
return {
//属性名与值为变量名的变量名相同的时候,可以简写省略值
scores,
min:'',
max:'',
subject:''
};
},
}
</script>

index.js

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
//自己加入的必须加载和要使用组件的代码 START
import Table2 from '@/components/Table2'
//自己加入的必须加载和要使用组件的代码 END
Vue.use(Router)
export default new Router({
routes: [
//http://localhost:8080/#/Table2
{
path: '/Table2',
name: 'Table2',//路由跳转时使用
component: Table2//记得写加载要使用的这个组件的代码
}
,
//自己加的代码 END
]
})
//解决重复点击路由,界面跳转等时报错的代码 START
const originalPush = Router.prototype.push
Router.prototype.push = function push (location) {
return originalPush.call(this, location).catch(err => err)
}
//解决重复点击路由,界面跳转等时报错的代码 END


科普(推荐好文):
https://www.cnblogs.com/liyanyan665/p/11192635.html
Vue - ElementUI中循环渲染表格,控制字段的显示与隐藏 v-if与v-for同时使用
在Vue中使用v-for循环一个数组/对象时,如果再使用v-if,那么会提示使用计算属性(能正常使用),因为Vue中是不提倡v-for与v-if同时使用的。
在我的项目中也遇到了问题
不过翻看文档解决了
修改前:
<el-table-column
v-for="(item, index) in columns"
:prop="item.prop"
:key="index"
align="center"
:width="item.width"
:label="item.label"
v-if="item.show"
>
></el-table-column>
编辑器提示:vue/no-use-v-if-with-v-for] The 'columns' variable inside 'v-for' directive should be replaced with a computed property that returns filtered array instead. You should not mix 'v-for' with 'v-if'.eslint-plugin-vue
修改后:
<template v-for="(item, index) in columns">
<el-table-column
:prop="item.prop"
:key="index"
align="center"
:width="item.width || '' "
:label="item.label"
v-if="item.show"
>
</el-table-column>
</template>
即使用template标签包裹即可,v-for 写在template 上,v-if 绑定在需要循环的元素之上即可
https://mp.weixin.qq.com/s?src=11×tamp=1621139141&ver=3071&signature=apMJgWY*vlL32v18XPBSkkT5s3Nip3huntQKliosDoSE5L6N*HlYXZgSHaQAoH6311YlNJfolCOSYBtdP2Hd0IgT9NybtY0hU0oS6KW1bsOGSgxCtK1kiscMV-2P0D6d&new=1

https://zhuanlan.zhihu.com/p/141238031

https://blog.csdn.net/weixin_44583625/article/details/93162611
