react 实现问卷调查(单选题目、多选题目)

问卷调查怎么写?

前台的逻辑部分也就是在——单选和多选的实现以及存储上面


第一步:首先了解数据的基本类型、格式——大致如下(两个单选题目,一个多选题目):

 state = {
        choose_data: [
            {
                title_num:'1',
                id: 1,
                key: '1',
                title: '【安全类】请选择您心目中的“职业形象达 人”',
                title_type: 1,
                choose_list: [
                    {
                        id: 1,
                        key: '1-1',
                        letter: 'A',
                        img: choose_pic,
                        content: '安全部-特勤-张XX',
                    },
                    {
                        id: 2,
                        key: '1-2',
                        letter: 'B',
                        img: choose_pic,
                        content: '安全部-特勤-赵XX',
                    }
                ]
            },
            {
                title_num:'2',
                id: 2,
                key: '2',
                title: '有安全意识的是',
                title_type: 1,
                choose_list: [
                    {
                        id: 1,
                        key: '1-1',
                        letter: 'A',
                        content: '我是选择一',
                    },
                    {
                        id: 2,
                        key: '1-2',
                        letter: 'B',
                        content: '我是选择2',
                    }
                ]
            },
            {
                title_num:'3',
                id: 3,
                key: '3',
                title: '是颜色的有',
                title_type: 2,
                choose_list: [
                    {
                        id: 1,
                        key: '1-1',
                        letter: 'A',
                        content: '我是选择一',
                    },
                    {
                        id: 2,
                        key: '1-2',
                        letter: 'B',
                        content: '我是选择2',
                    },
                    {
                        id: 3,
                        key: '1-3',
                        letter: 'C',
                        content: '我是选择2',
                    }
                ]
            }
        ],
        answer: [],  //存储选择的答案(以数组包裹对象的方式来存储)
    }

包括的内容:题目id(题目标题、单选还是多选、题号等),第二层是选项的内容(每个选项的id、内容等)

第二步 引入antd单选多选标签

import { Radio,Checkbox  } from 'antd';

该情景下的单选多选框略有不同,所以需要利用选框组的形式来实现(为了确保每个题目的答案选择不会跟其他题目冲突):
所以还需要声明选框组的标签

const RadioGroup = Radio.Group;
const CheckboxGroup = Checkbox.Group;

第三步 页面的呈现方式

 <ul className={styles.topic_list_box}>
    {
        data.map((item) => {
            return (
                <li key={item.id}>
                    <p><span className={styles.title_num}>{`${item.title_num}.`}</span>{item.title}<span className={styles.topic_type}>{item.title_type===1?'单选题':'多选题'}</span></p>
                    <ul className={styles.choose_list}>
                        {
                            item.title_type===1?
                            <RadioGroup name="radiogroup" onChange={this.change_radio.bind(this, item.id)}>
                                {
                                    item.choose_list.length > 0 ?
                                        item.choose_list.map((item1) => {
                                            return (
                                                <li key={item1.id}>
                                                    {item1.img ? <img src={item1.img} alt="choose_pic" /> : ''}
                                                    <div className={styles.content}>
                                                        <span>{`${item1.letter}.`}</span>
                                                        <Radio
                                                            value={item1.letter}
                                                        >{item1.content}</Radio>
                                                    </div>
                                                </li>
                                            )
                                        }) : ''
                                }
                            </RadioGroup>:
                            <CheckboxGroup onChange={this.change_radio.bind(this, item.id,'checkbox')}>
                                {
                                    item.choose_list.length > 0 ?
                                        item.choose_list.map((item1) => {
                                            return (
                                                <li key={item1.id}>
                                                    {item1.img ? <img src={item1.img} alt="choose_pic" /> : ''}
                                                    <div className={styles.content}>
                                                        <span>{`${item1.letter}.`}</span>
                                                        <Checkbox
                                                            value={item1.letter}
                                                        >{item1.content}</Checkbox>
                                                    </div>
                                                </li>
                                            )
                                        }) : ''
                                }
                            </CheckboxGroup>

                        }
                    </ul>
                </li>
            )
        })
    }
</ul>

基本逻辑:如果是单选题的话,按照单选的格式来渲染,否则按照复选的格式来渲染(都是一组的格式),因为这样才能保证每道题目都是独立的
事件:onChange()
因为单选和多选事件中的参数代表的是不同的意思,所以需要区分一下

//选择
    change_radio(title_id, e,str) {
        const answer_current = this.state.answer;                           //原本state数组中存储的数据
        const answer_new = { title: title_id, choose_id: e==='checkbox'?str:e.target.value}   //最新原则的题目以及对应的答案
        answer_current.map((item) => {
            if (item.title === title_id) {                                  //如果原来的数组中题号存在和最新的一样的,则要剔除
                answer_current.splice(answer_current.indexOf(item), 1)
            }
        })
        //把最新的答案拼接到原来的数组中
        this.setState({
            answer: this.state.answer.concat(answer_new)
        })
    }

事件逻辑:
state中answer代表的是现有的答案(即在事件中重新声明之后的answer_current ),变量answer_new 代表的是用户最新选择的题目以及对应的答案,也就是说需要把新的答案存储到answer中之外,还要判断answer中是否有同样的题目的答案,有的话则需要删除掉。
至于==answer_new ==
choose_id要根据e来判定是因为,单选事件和多选事件中的参数不一样,
如果是单选e代表的是事件对象,str是undefined,
如果是多选,e代表的是我们传递进去的参数‘checkbox’,str则代表我选中的答案,所以是这样一个格式

猜你喜欢

转载自blog.csdn.net/baidu_41604826/article/details/83069868