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>