问题 : 最初做多选功能时发现,当多选的题数超过一个时,选择一个选项那么所有题的该选项都会被选中,这是因为用v-for遍历的时候都绑定了同一个事件。 解决 : 给每一题设置不同的名字,那么他们的选项就不会发生联动了。
js 参考博文链接地址:https://blog.csdn.net/shaonaozu/article/details/12704951
软件:vscode
技术:vue + Elementui + 事件绑定
需求:多组选择,每组之间互不影响。每组均可多选,第一次单击选中且改变颜色,第二次单击不选中且颜色默认
主内容如下:
一、在 src/utils/创建 xxx.js 文件
- 要使用哪个函数,就一定要export;
- 本例中export add 和 remove。
const separator = ","
const baforeInsert = false
const isRepeat = false
const isDeleteAll = true
function lInsertSeparator(operateString) {
if(operateString.indexOf(separator) == 0){
return operateString;
}
return separator + operateString;
}
function rInsertSeparator (operateString) {
if(operateString.lastIndexOf(separator) == (operateString.length - separator.length))
return operateString;
return operateString + separator;
}
function lSeparatorTrim (operateString) {
if(operateString.indexOf(separator) == 0)
return operateString.substring(1);
return operateString;
}
function rSeparatorTrim (operateString) {
if(operateString.lastIndexOf(separator) == (operateString.length - separator.length))
return operateString.substring(0,operateString.length-1);
return operateString;
}
export function add(operateString, str) {
if( str && str != ""){
if(isRepeat){
if(baforeInsert){
return rSeparatorTrim(lSeparatorTrim(str + separator + operateString));
}
return rSeparatorTrim(lSeparatorTrim(operateString + separator + str));
}else{
operateString = lInsertSeparator(rInsertSeparator(operateString));
if(operateString.indexOf(separator + str + separator) == -1){
if(baforeInsert){
return rSeparatorTrim(lSeparatorTrim(str + operateString));
}else{
return rSeparatorTrim(lSeparatorTrim(operateString + str));
}
}
return rSeparatorTrim(lSeparatorTrim(operateString));
}
}
}
export function remove(operateString, str) {
if(operateString && str && operateString != "" && str != ""){
operateString = lInsertSeparator(rInsertSeparator(operateString));
if(isDeleteAll){
operateString = operateString.replace(new RegExp(separator,"g"),separator + separator);
operateString = operateString.replace(new RegExp(separator + str +separator,"g"),separator);
operateString = operateString.replace(new RegExp(separator+"{2,}","g"),separator);
}else{
operateString = operateString.replace(new RegExp(separator + str + separator),separator);
}
return rSeparatorTrim(lSeparatorTrim(operateString));
}
}
二、在 src/views/xxx/创建.vue文件
- 将上述创建的.js文件引入 (script标签中引);
- 注意一定要import 且 如果想在其余地方多次使用该.js文件,可以在当前.vue文件引入时起一个别名;
- 本例中 add as addOption。
- 先布局 | 再遍历样式 | 然后给每一题设置不同的 id | 再分别设置每一题每一个选项 | 同时绑定事件
<template>
<div class="total">
<el-row :span="10">
<!-- 题型 -->
<div class="multititle">多选题</div>
<el-row
class="multitlcard"
v-for="(multi, index) in MultiQuestionList"
:key="index"
>
<!-- 题目 -->
<el-row class="question">
<span :id="multi.id">{{ index + 1 }}</span>
<span class="questiontitle">.{{ multi.title }}</span>
</el-row>
<!-- 选项 -->
<el-row class="items">
<div class="item" :id="`${multi.id},a`" @click="setMultilAnswer">
<span
:class="multi.answer.indexOf('a') != -1 ? 'active' : 'noactive'"
>A</span
>
<span>{{ multi.item_a }}</span>
</div>
<div class="item" :id="`${multi.id},b`" @click="setMultilAnswer">
<span
:class="multi.answer.indexOf('b') != -1 ? 'active' : 'noactive'"
>B</span
>
<span>{{ multi.item_b }}</span>
</div>
<div class="item" :id="`${multi.id},c`" @click="setMultilAnswer">
<span
:class="multi.answer.indexOf('c') != -1 ? 'active' : 'noactive'"
>C</span
>
<span>{{ multi.item_c }}</span>
</div>
<div class="item" :id="`${multi.id},d`" @click="setMultilAnswer">
<span
:class="multi.answer.indexOf('d') != -1 ? 'active' : 'noactive'"
>D</span
>
<span>{{ multi.item_d }}</span>
</div>
</el-row>
</el-row>
</el-row>
</div>
</template>
<script>
import {add as addOption,remove as removeOption} from "@/刚创建的.js的路径"
export default {
data() {
return {
MultiQuestionList: [
{
id: 111,
title: "这是第一道多选题",
type: "multi",
item_a: "1-选项一",
item_b: "1-选项二",
item_c: "1-选项三",
item_d: "1-选项四",
answer: "",
},
{
id: 112,
title: "这是第二道多选题",
type: "multi",
item_a: "2-选项一",
item_b: "2-选项二",
item_c: "2-选项三",
item_d: "2-选项四",
answer: "",
},
],
};
},
methods: {
setMultilAnswer(e) {
var element = e.currentTarget;
var arr = element.id.split(",");
var multiId = arr[0];
var item = arr[1];
for (var i = 0; i < this.MultiQuestionList.length; i++) {
if (this.MultiQuestionList[i].id == multiId) {
if (this.MultiQuestionList[i].answer.indexOf(item) != -1) {
this.MultiQuestionList[i].answer = removeOption(
this.MultiQuestionList[i].answer,
item
);
} else {
this.MultiQuestionList[i].answer = addOption(
this.MultiQuestionList[i].answer,
item
);
}
return;
}
}
return;
},
},
};
</script>
<style scoped>
.total {
margin: 10px;
}
.multititle {
width: 100%;
height: 30px;
line-height: 30px;
background-color: beige;
}
.multitlcard {
margin-top: 10px;
}
.question {
font-size: 16px;
}
.item {
margin: 10px;
}
.item > span {
display: inline-block;
}
.noactive {
border: 1px solid #004f00;
width: 22px;
height: 22px;
line-height: 22px;
text-align: center;
cursor: pointer;
}
.active {
border: 1px solid #004f00;
width: 22px;
height: 22px;
line-height: 22px;
text-align: center;
color: #fff;
background-color: darkorange;
cursor: pointer;
}
</style>
三、运行结果
-
多选且变色 -
取消则默认
|