You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue多选项题目应用:单题反转按钮引发全题选项同步变更问题

问题:Vue题目选项反转按钮触发全量选项反转的排查与解决

这是一个带多选项题目的Vue应用,每题配有选项反转按钮。操作流程如下:

  • 第一步:在textarea输入题目(示例输入:
    1. I can quickly tell when I'm angry
    2. I know how I look and behave when I’m angry
    3. I can clearly distinguish between different degrees of happiness
    4. I can tell the difference between being sad and being angry
      )后,点击「Next Step」进入第二步。
  • 第二步:展示所有题目及对应反转按钮,点击某题反转按钮时,预期仅该题选项反转,但实际所有题目选项均被反转,需解决此异常。

完整代码如下:

<template>
  <div class="">
      <div class="flex flex-col space-y-2" v-if="step==0">
        <div class="flex flex-row space-x-2">
          <button type="button" class="p-2 bg-blue-600 mx-2 text-sm font-semibold text-white rounded-md"  @click="step=1;handleQuestions(data)"><span>Next Step</span></button>
        </div>

        <div class="flex flex-row space-x-5">

              <el-input type="textarea" :rows="12" placeholder="Please input" v-model="data"> </el-input>

              <div class="w-1/5" >
                <div class="flex flex-col space-y-1" v-for="(item, index) in defaultOptions" :key="index">
                    <div class="flex flex-row space-x-5">
                      <el-input class="w-24" placeholder="label" v-model="item.label"></el-input>
                      <el-input class="w-24" placeholder="score" v-model="item.score"></el-input>
                    </div>
                </div>
              </div>
         </div>
      </div>

      <div class="flex flex-col space-y-2 max-h-screen bg-white p-2 rounded-lg" v-if="step==1">
          <div class="flex items-center justify-between w-full">
            <button type="button" class="p-2 bg-blue-600 mx-2 text-sm font-semibold text-white rounded-md"  @click="step=0"><span>Previous Step</span></button>
          </div>
          <div class="overflow-y-auto flex flex-col space-y-2" >
            
              <div class="flex flex-col space-y-1" v-for="(question, index) in questions" :key="index">
                <div class=" text-base mb-2" >  
                  <span class="flex flex-row space-x-1" >
                      <span class="text-xl w-10"> {{index + 1}}. </span>
                      <!-- <InputEditor class="text-sm  w-full" :value="question.name" @input="updateEditor($event,'name')"></InputEditor> -->
                      <span class="text-xl w-5/6 w-full"> {{index + 1}} {{  question.name  }} </span>
                      <i class="el-icon-s-order" @click="reserveOptions(index)"> </i>
                  </span>
                </div>             
                <el-radio-group class="flex space-x-3" >
                    <el-radio v-for="(question, index2) in question.options" :key="index2" :label="question" style="width: 100%">
                        {{ question.label }}
                    </el-radio>
                </el-radio-group>
              </div>
          </div>  
      </div>          

  </div>
</template>

<script >
export default {
  name: 'Editor',
  components: {  },
  data: function () {
    return {
      data:'',
      step:0,
      questions:[],
      defaultOptions:[
        {'label':'very bad','score':1},
        {'label':'not bad','score':0},
        {'label':'ok','score':1},
        {'label':'good','score':2},
        {'label':'best','score':3},
      ]
    }
  },
  methods: {
    handleQuestions(codes){
      let lines = codes.split('\n');
      let lineArray = [];
      let questions = [];
      for(let i=0;i<lines.length;i++){
          let line = lines[i].trimStart();
          if(line ===  ''){
            console.log('empty line',i,line);
          }else{
            console.log('line',line);
            lineArray.push(line);
          }
      }
      console.log('lineArray',lineArray);
      
      for(let i=0;i<lineArray.length;i++){
          let question = lineArray[i];
          questions.push({name:question,options: this.defaultOptions });          
      }
      this.questions = questions;
    },
    reserveOptions(index) {
      this.questions[index].options = this.questions[index].options.reverse();
    }, 
  }
}
</script>

问题原因

所有题目共享了同一个defaultOptions数组的内存引用。在handleQuestions方法中,每个question的options直接赋值为this.defaultOptions,这意味着所有题目指向的是同一个数组对象。当调用reverse()反转其中一个题目的选项时,实际修改的是这个共享数组,因此所有题目都会同步变化。

解决方案

为每个题目创建独立的选项数组副本,避免引用共享。修改handleQuestions方法中添加question的逻辑,使用数组拷贝方式生成新数组:

// 原代码
questions.push({name:question,options: this.defaultOptions });          
// 修改为以下任意一种方式即可
questions.push({name:question,options: [...this.defaultOptions] });          
// 或使用slice()
questions.push({name:question,options: this.defaultOptions.slice() });          
// 或使用Array.from()
questions.push({name:question,options: Array.from(this.defaultOptions) });          

修改后,每个题目拥有独立的options数组,点击单个题目的反转按钮时,只会修改当前题目的选项,其他题目不受影响。

内容的提问来源于stack exchange,提问作者user824624

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 05:50:11