请问前端用js如何实现限制每道题都需要填才能通过,不填会uni.toast?


<template>
    <view class="questionnaire">
        <view class="section">
            <view class="title">
                一、财务状况
            </view>
            
            <view class="container">
                <view class="content">
                    <view class="question" v-for="(item,index) in questionList.slice(0,3)" :key='index'>
                        <view class="question_header">
                            <view class="header_title">{{item.subjectContent}}<text style="font-weight: 500;">{{item.type==0?'':'(多选)'}}</text></view>
                        </view>
                        <view class="question_option">
                            <view :class="{option_item:true,active_option:items.id==items.active}"  v-for="(items,indexs) in item.optionList" :key='indexs' @click="optionItem(items)">
                                <view class="option_box">
                                    <image src="../../../static/hook.png" mode=""></image>
                                </view>
                                <text>{{items.optionContent}}</text>
                            </view>
                        </view>
                    </view>
                    <view style="height: 40rpx;">
                        
                    </view>
                </view>
                
                
                
            </view>
            
            
            
        
        </view>
    
        
        
        <view class="section">
            <view class="title">
                二、投资经验(任一项选A客户均视为无投资经验客户)
            </view>
            
            <view class="container">
                <view class="content">
                    <view class="question" v-for="(item,index) in questionList.slice(3,5)" :key='index'>
                        <view class="question_header">
                            <view class="header_title">{{item.subjectContent}}<text style="font-weight: 500;">{{item.type==0?'':'(多选)'}}</text></view>
                        </view>
                        <view class="question_option">
                            <view :class="{option_item:true,active_option:items.id==items.active}"  v-for="(items,indexs) in item.optionList" :key='indexs' @click="optionItem(items)">
                                <view class="option_box">
                                    <image src="../../../static/hook.png" mode=""></image>
                                </view>
                                <text>{{items.optionContent}}</text>
                            </view>
                        </view>
                    </view>
                    <view style="height: 40rpx;">
                        
                    </view>
                </view>
                
                
                
            </view>
            
            
            
        
        </view>
        
        
        <view class="section">
            <view class="title">
                三、投资风格
            </view>
            
            <view class="container">
                <view class="content">
                    <view class="question" v-for="(item,index) in questionList.slice(5,7)" :key='index'>
                        <view class="question_header">
                            <view class="header_title">{{item.subjectContent}}<text style="font-weight: 500;">{{item.type==0?'':'(多选)'}}</text></view>
                        </view>
                        <view class="question_option">
                            <view :class="{option_item:true,active_option:items.id==items.active}"  v-for="(items,indexs) in item.optionList" :key='indexs' @click="optionItem(items)">
                                <view class="option_box">
                                    <image src="../../../static/hook.png" mode=""></image>
                                </view>
                                <text>{{items.optionContent}}</text>
                            </view>
                        </view>
                    </view>
                    <view style="height: 40rpx;">
                        
                    </view>
                </view>
                
                
                
            </view>
            
            
            
        
        </view>
                
        
        <view class="section">
            <view class="title">
                四、投资目的
            </view>
            
            <view class="container">
                <view class="content">
                    <view class="question" v-for="(item,index) in questionList.slice(7,9)" :key='index'>
                        <view class="question_header">
                            <view class="header_title">{{item.subjectContent}}<text style="font-weight: 500;">{{item.type==0?'':'(多选)'}}</text></view>
                        </view>
                        <view class="question_option">
                            <view :class="{option_item:true,active_option:items.id==items.active}"  v-for="(items,indexs) in item.optionList" :key='indexs' @click="optionItem(items)">
                                <view class="option_box">
                                    <image src="../../../static/hook.png" mode=""></image>
                                </view>
                                <text>{{items.optionContent}}</text>
                            </view>
                        </view>
                    </view>
                    <view style="height: 40rpx;">
                        
                    </view>
                </view>
                
                
                
            </view>
            
            
            
        
        </view>
                
        <view class="section">
            <view class="title">
                五、风险承受能力
            </view>
            
            <view class="container">
                <view class="content">
                    <view class="question" v-for="(item,index) in questionList.slice(9,11)" :key='index'>
                        <view class="question_header">
                            <view class="header_title">{{item.subjectContent}}<text style="font-weight: 500;">{{item.type==0?'':'(多选)'}}</text></view>
                        </view>
                        <view class="question_option">
                            <view :class="{option_item:true,active_option:items.id==items.active}"  v-for="(items,indexs) in item.optionList" :key='indexs' @click="optionItem(items)">
                                <view class="option_box">
                                    <image src="../../../static/hook.png" mode=""></image>
                                </view>
                                <text>{{items.optionContent}}</text>
                            </view>
                        </view>
                    </view>
                    <view style="height: 40rpx;">
                        
                    </view>
                </view>
                
                
                
            </view>
            
            
            
        
        </view>
                
        
        <view style="margin:10px;padding:10px;padding-left: 0px;margin-top:20px;">
            <van-button round block color="rgb(215,0,15)"  @click="subQuestion">
                提交
            </van-button>
        </view>
    </view>
</template>
<script>
    export default{
        data(){
            return{
                active:0,
                questionList:[],
                sumOfMask:0
            }
        },
        created() {
            this.getQuestionList()
        },
        onLoad() {
        },
        methods:{
            
            // 提交问卷
            subQuestion(){
                var activeQuestion = []//问题选择列表
                // 循环判断active是否为空,单选和多选因为传参格式需要区分判断
                for(var i in this.questionList){
                    // 单选判断循环
                    if(this.questionList[i].type==0){
                        // console.log('单选')
                        for(var j in this.questionList[i].optionList){
                            if(this.questionList[i].optionList[j].active != ''){
                                activeQuestion.push({
                                    id:this.questionList[i].id,
                                    mask:Number(this.questionList[i].optionList[j].mask),
                                    
                                })
                                // console.log('单选:',activeQuestion)
                            }
                            
                        }
                    }else if(this.questionList[i].type==1){
                        console.log('多选')
                        // 多选判断循环,选项ID以逗号拼接成字符串
                        var optionArr = []
                        var totalMask = 0
                        for(var j in this.questionList[i].optionList){
                            if(this.questionList[i].optionList[j].active != ''){
                                totalMask +=Number(this.questionList[i].optionList[j].mask)
                                optionArr.push(this.questionList[i].optionList[j].mask)
                                // optionArr.push(this.questionList[i].optionList[j].id)
                                console.log('totalMask:',totalMask)
                                console.log('optionArr:',optionArr)
                            }
                            
                        }
                        // 统计选择的数据
                        activeQuestion.push({
                            // mask:optionArr.join(),
                            mask:totalMask
                        
                        })
                        console.log('多选:',activeQuestion)
                    }
                }
                console.log('所有:',activeQuestion)
                var choosedId=[]
                for(var item in activeQuestion){
                    choosedId.push(Number(activeQuestion[item].id))
                    
                }
                for(var item in activeQuestion){
                    for(var questionId=1;questionId<11;questionId++){
                        
                        if(!choosedId.includes(questionId)){
                            uni.showToast({
                                      title:'第'+questionId+'题尚未选择',
                                      duration: 2000,
                                      icon:'none'
                                });
                            break
                        }else{
                            this.sumOfMask+=Number(activeQuestion[item].mask)
                            
                        }
                        
                        
                    }
                    
                console.log('最后的mask:',this.sumOfMask)
                
                }
                
                
            //     for(var item in activeQuestion){
            //         // console.log('activeQuestion[item].id:',activeQuestion[item].id)
            //         var id = Number(item)+Number(1)
            //         if(activeQuestion[item].mask==null){
            //             console.log('为空')
            //             uni.showToast({
            //                       title:'第'+id+'题尚未选择',
            //                       duration: 2000,
            //                       icon:'none'
            //                 });
            //         }else{
            //             console.log('activeQuestion[item].mask:',activeQuestion[item].mask)
            //             this.sumOfMask+=Number(activeQuestion[item].mask) 
            //         }
            //     }
            
            },
            // 选择及未选择样式切换
            optionItem(param){
                // 根据每个字段的id作为唯一状态标识是否选中
                this.active=param.id
                for(var i in this.questionList){
                    // 单项选择
                    if(this.questionList[i].type == 0){
                        if(this.questionList[i].id == param.subjectId){
                            for(var j in this.questionList[i].optionList){
                                    if(this.questionList[i].optionList[j].id == param.id && this.questionList[i].optionList[j].active==''){
                                        this.questionList[i].optionList[j].active=param.id
                                    }else{
                                        this.questionList[i].optionList[j].active=''
                                    }
                                }
                        }
                        // 多项选择
                    }else if(this.questionList[i].type == 1){
                        for(var j in this.questionList[i].optionList){
                                if(this.questionList[i].optionList[j].id == param.id){
                                    if( this.questionList[i].optionList[j].active==''){
                                        this.questionList[i].optionList[j].active=param.id
                                    }else if( this.questionList[i].optionList[j].active!=''){
                                        this.questionList[i].optionList[j].active=''
                                    }
                                }
                            }
                        
                    }
                }
            },
            getQuestionList(){
                // 问卷数据格式
    var data = [
        {
            "id": "1",
            "subjectContent": "1. 您的年龄是?",
            "type": 0,
            "sort": 0,
            "state": 1,
            "optionList": [
                {
                    "id":'1_A',
                    "subjectId": "1",
                    "optionContent": "18-30岁",
                    "mask":'-2'
                },
                {
                    
                    "id":'1_B',
                    "subjectId": "1",
                    "optionContent": "31-50岁",
                    "mask":'0'
                },
                {
                   
                    "id":'1_C',
                    "subjectId": "1",
                    "optionContent": "51-60岁",
                    "mask":'-4'
                },
                {
                   
                    "id":'1_D',
                    "subjectId":'1',
                    "optionContent": "高于60岁",
                    "mask":'-10'
                }
            ]
        },
        {
            "id": "2",
            "subjectContent": "2. 您的家庭年收入为(折合人民币)?",
            "type": 0,
            "sort": 0,
            "state": 1,
            "optionList": [
                {
                    "id": "2_A",
                    "subjectId": "2",
                    "optionContent": "5万元以下",
                    "mask":'0'
                },
                {
                    "id": "2_B",
                    "subjectId": "2",
                    "optionContent": "5-20万元",
                    "mask":'2'
                },
                {
                    "id": "2_C",
                    "subjectId": "2",
                    "optionContent": "20-50万元",
                    "mask":'6'
                },
                {
                    "id": "2_D",
                    "subjectId": "2",
                    "optionContent": "50-100万元",
                    "mask":'8'
                },
                {
                    "id": "2_E",
                    "subjectId": "2",
                    "optionContent": "100万元以上",
                    "mask":'10'
                }
                
            ]
        },
        {
            "id": "3",
            "subjectContent": "3. 在您每年的家庭收入中,可用于金融投资(储蓄存款除外)的比例为?",
            "type": 0,
            "sort": 0,
            "state": 1,
            "optionList": [
                {
                    "id":'3_A',
                    "subjectId": "3",
                    "optionContent": "小于10%",
                    "mask":'2'
                },
                {
                    
                    "id":'3_B',
                    "subjectId": "3",
                    "optionContent": "10%至25%",
                    "mask":'4'
                },
                {
                   
                    "id":'3_C',
                    "subjectId": "3",
                    "optionContent": "25%至50%",
                    "mask":'8'
                },
                {
                   
                    "id":'3_D',
                    "subjectId":'3',
                    "optionContent": "大于50%",
                    "mask":'10'
                }
            ]
        },
        
        
        
        
        
    ]
                    // 每个问卷都加上状态字段active
                    for(let i in data){
                        var optionList=[]
                        for(let j in data[i].optionList){
                            data[i].optionList[j].active=''
                            optionList.push(data[i].optionList[j])
                        }
                        data[i].optionList=optionList
                    }
                    this.questionList =data
            },
            
            
            
        }
    }
</script>

<style lang="less" scoped>
    .questionnaire{
            margin: 10px auto;
            margin-bottom: 5px;
    }
    .title{
            margin-bottom: 10px;
            margin-left: 15px;
            margin-top: 5px;
            font-size: 18px;
            font-weight: 550;
    }
    
    .question{
        .question_header{
            // height: 90rpx;
            padding: 8px 0px;
            line-height: 1.5;
            background-color: #f1f1f1;
            font-size: 16px;
            font-weight: 700;
            color: #333333;
            .header_title{
                    margin: 0 37rpx;
            }
        }
        .question_option{
            width: 650rpx;
            margin-top: 7rpx;
            // background-color: #F0AD4E;
            // display: flex;
            justify-content: space-between;
            flex-wrap: wrap;
            margin: 0 auto;
            margin-bottom: 40rpx;
            .option_item{
                // width: 300rpx;
                margin-top: 34rpx;
                // background-color: #DD524D;
                font-size: 30rpx;
                color: #666666;
                display: flex;
                align-items: center;
                .option_box{
                    min-width: 35rpx;
                    height: 35rpx;
                    border: 1rpx solid #999999;
                    border-radius: 5px;
                    margin-right: 10rpx;
                    // background-color: #FF852A;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    image{
                        width: 20rpx;
                        height: 20rpx;
                    }
                }
            }
        }
    }
    .active_option{
        .option_box{
            // background: linear-gradient(-30deg,#ff7029 0%, #faa307 100%);
            // border: 1rpx solid #faa307 !important;
            background-color: red;
            border: 1rpx solid rgb(215,0,15) !important;
        }
        text{
            color: rgb(212,0,12);
        }
    }
    .submit_box{
        width: 750rpx;
        height: 160rpx;
        background-color: #F1F1F1;
        position: fixed;
        bottom: 0;
    }
    .sub_btn{
        width: 690rpx;
        height: 88rpx;
        background: linear-gradient(-30deg,#dc4011 0%, #faa307 100%);
        border-radius: 44rpx;
        margin: 40rpx auto;
        font-size: 16px;;
        font-weight: 700;
        color: #ffffff;
        text-align: center;
        line-height: 88rpx;
    }
    // 按钮原生会存在上下黑线,该属性去除
    button::after{ border: none;}
</style>

以上为前端的调查问卷组件,请问如何用js实现限制每道题都必填,不填会弹出toast弹窗

img


请赐教,不胜感激。

要么你用form表单的验证属性,或者你在click点击事件触发的时候去检验一下上一个选项的值有没有选择,没有的话就提示弹框然后return

form 必填选项 。或者 提交 接口 对字段值做个判断 不为 空,不为 undefin、null