UI设计稿
在这里插入图片描述
如果是定义好的,数目不多的话。可能就会写死。几道题目就在data里,写几个对应v-model绑定的对应值。(插一句在vue中选中状态,不能checked,selected作为选中状态,vue是数据绑定的,也就是说data中绑定初始值来默认选中。)
可是实际项目需求是 遍历问卷调查列表页,之后动态遍历问卷详情,也就是上图。如果只是渲染视图,应该没什么问题,关键在于v-model绑定值的处理。要动态处理。

找了几天的案例,终于在昨天在网上找到一篇大佬的文章:地址 https://www.cnblogs.com/shuangzikun/p/python_taotao_vue_question.html再根据自己的实际项目

<!-- 问卷详情 -->
<template>
  <div class="wjxq">
    <form @submit.prevent="submit">
      <ul class="question_ul">
        <li class="question_li" v-for="(item,index) in list" :key='index'>
          <p class="title">{{index+1}}.{{item.name}}</p>

          <div class="question_li_wrap">
            <label>
              <input type="radio" :name="item.name" value='A' v-model="checkedValue[index]" @change="get_radio_value(index)"><span>{{item.answer1}}</span>
              <div></div>
            </label>
          </div>
          <div class="question_li_wrap">
            <label>
              <input type="radio" :name="item.name" value='B' v-model="checkedValue[index]" @change="get_radio_value(index)"><span>{{item.answer2}}</span>
              <div></div>
            </label>
          </div>
          <div class="question_li_wrap">
            <label>
              <input type="radio" :name="item.name" value='C' v-model="checkedValue[index]" @change="get_radio_value(index)"><span>{{item.answer3}}</span>
              <div></div>
            </label>
          </div>
          <div class="question_li_wrap">
            <label><input type="radio" :name="item.name" value='D' v-model="checkedValue[index]" @change="get_radio_value(index)"><span>{{item.answer4}}</span>
              <div></div>
            </label>
          </div>

        </li>
      </ul>
      <button class="submit" type="submit">提交</button>
    </form>
  </div>
</template>

<script>
export default {
  data() {
    return {
      list: {}, //单选详情页数组
      all_list: [], //答案数组
      checkedValue: [] //绑定单选框的值
    };
  },
  created() {
    var id = this.$route.query.id;
    this.getMessage(id);
  },
  methods: {
    getMessage(id) {
      this.$http
        .get("api/v2/diaocha/wenjuanList?diaocha_id=" + id)
        .then(res => {
          this.list = res.data.data.items;
          console.log(res.data.data);
        });
    },
    submit: function() {
      console.log(this.all_list,"答案");
      for (var i = 0; i < this.all_list.length; i++) {
        if (this.all_list[i] == "" || typeof this.all_list[i] === "undefined") {
          this.all_list.splice(i, 1);
        }
      }  // 数据
      //循环

        if (this.list.length !== this.all_list.length) {
          alert("答案没有回答完整");
        } else {
          console.log("答案选择完毕");
          // 传值给调用页面
          // this.$emit('transfer', this.all_list)
      }
    },
    get_radio_value: function(index) {
      // 获取当前radio当前值
      console.log(index + 1 + "题" + this.checkedValue[index]);
      // console.log((index + 1) + '题' + this.checkedValue)
      this.all_list[index] = this.checkedValue[index]; //赋值
    }
  }
};
</script>
<style lang='css' scoped>
.wjxq {
  width: 100%;
  height: 100%;
}
.question_ul {
  width: 100%;
  padding: 0.5rem 0.5rem;
}
.question_li {
  margin-bottom: 0.6rem;
}
.question_li .title {
  font-size: 0.3rem;
  font-weight: 400;
  color: rgba(51, 51, 51, 1);
  line-height: 0.42rem;
}
.question_li_wrap {
  position: relative;
  display: flex;
  align-items: center;
  width: 4.34rem;
  height: 0.55rem;
  /* background: linear-gradient(
    135deg,
    rgba(255, 146, 146, 1) 0%,
    rgba(255, 68, 68, 1) 100%
  ); */
  border-radius: 0.05rem;
  margin-top: 0.1rem;
  margin-bottom: 0.1rem;
  padding-left: 0.1rem;
}
.question_li span {
  margin-left: 0.18rem;
}
label {
  position: relative;
  display: flex;
  align-items: center;
  width: 4.3rem;
  height: 0.55rem;
  padding-left: 0.1rem;
  /* background: blue; */
}
.question_li input[type="radio"]:checked span {
  color: white;
}
.question_li input[type="radio"]:checked ~ div {
  position: absolute;
  top: 0;
  left: 0;
  width: 4.3rem;
  height: 0.55rem;
  background: linear-gradient(
    135deg,
    rgba(255, 146, 146, 1) 0%,
    rgba(255, 68, 68, 1) 100%
  );
  border-radius: 0.05rem;
  color: white;
  z-index: -9999999999;
}
.wjxq .submit {
  display: block;
  width: 2rem;
  height: 0.5rem;
  line-height: 0.5rem;
  text-align: center;
  color: white;
  margin: 20px auto 80px;
  background: linear-gradient(
    135deg,
    rgba(255, 146, 146, 1) 0%,
    rgba(255, 68, 68, 1) 100%
  );
}
</style>

在这里插入图片描述
功能实现,完美

最后附上一段大佬的代码,有多选的,以备不时之需(抽离组件,父子传递)

<template>
  <div class="aaaa">
    <div class="div" v-for="(son,index) in list_a" :key="index">
      <div class="question">问题:{{son.question }}</div>
      <div class="type">类型:{{son.type=== 1 ? '单选' : '多选' }}</div>
      <div v-if="son.type === 1" class="answer">
        <li v-for="(sson,index1) in son.answer" :key="index1" >
          <span>{{sson.value}}</span>
          <input type="radio" :name="son.name"  :value="sson.value" @change="get_radio_value(index)" v-model="checkedValue[index]" >
        </li>
        <div style="clear: both"></div>
      </div>
      <div v-else class="answer">
        <li v-for="(sson,index1) in son.answer" :key="index1">
          <span>{{sson.value}}</span>
          <input type="checkbox" :name="son.name" :value="sson.value" @change="get_checkbox_value(index)" v-model="checkedValue1" >
        </li>
      </div>
      <hr>
    </div>
    <button @click="btnfun">提交</button>
 </div>
</template>

<script>
export default {
  name: 'input8',
  data: function () {
    return {
      all_list: [],
      checkedValue: [], // 绑定单选框的值
      checkedValue1: [] // 绑定复选框的值
    }
  },
  props: ['list_a'],
  methods: {
    btnfun: function () {
      // 获取input框的值
      console.log(this.all_list)
      // 如果答案长度不匹配list_a
      // this.all_list = this.all_list.null
      // console.log(this.all_list)
      for (var i = 0; i < this.all_list.length; i++) {
        if (this.all_list[i] === '' || typeof (this.all_list[i]) === 'undefined') {
          this.all_list.splice(i, 1)
        }
      }
      // 循环
      if (this.list_a.length !== this.all_list.length) {
        console.log('答案没有选择完毕')
      } else {
        console.log('答案选择完毕')
        // 传值给调用页面
        this.$emit('transfer', this.all_list)
      }
    },
    get_radio_value: function (index) {
      // 获取当前radio当前值
      console.log((index + 1) + '题' + this.checkedValue)
      this.all_list[index] = this.checkedValue[index]
    },
    get_checkbox_value: function (index) {
      // 获取当前复选框的值
      console.log((index + 1) + '题' + this.checkedValue1)
      this.all_list[index] = this.checkedValue1
    }
  }
}
</script>
<style scoped>
li{
  list-style: none;
}
.div{
  margin: 6px 0px;
}
.question {
  width:300px;
  text-align: left;
}
.type{
  width:200px;
  text-align: left;
}
.answer li{
  width:100%;
  height: 20px;
}
.answer span{
  float: left;
}
.answer input{
  float: right;
}
</style>
Logo

前往低代码交流专区

更多推荐