当前位置: 首页 > 知识库问答 >
问题:

javascript - 如何实现这样一个布局?

司承业
2023-06-22

image.png
要求是这样的(目前的话换行单选多选判断换行展示已经处理完了):
image.png
但是现在有个问题就是选项的个数问题,选项最多是9个(也就是从A~I),最少是3~4个(判断的选项就是两个,但是若遇到判断就换行了,倒是不用太操心),选项个数不固定每题的宽度就不固定,宽度不固定列数就不固定,列数有影响到了行数,但又要求每列得对齐。
大致就是:
1.选项个数不固定
2.支持横排、竖排的切换
3.每列得对齐
所以想问问各位怎么实现这个需求?
数据:


        list:[{
          title: '1.单选题(8分)',
          idProp: 'questionId',
          code: 'single_choice',
          choices: [
            { identifier: 'A', content: '茂陵刘郎秋风客,夜闻马嘶晓无迹' },
            { identifier: 'B', content: '画栏桂树悬秋香,三十六宫土花碧' },
            { identifier: 'C', content: '魏官牵车指千里,东关酸风射眸子' },
            { identifier: 'D', content: '空将汉月出宫门,忆君清泪如铅水' },
            { identifier: 'E', content: '空将汉月出宫门,忆君清泪如铅水' },
            { identifier: 'F', content: '空将汉月出宫门,忆君清泪如铅水' },
            { identifier: 'G', content: '空将汉月出宫门,忆君清泪如铅水' },
            { identifier: 'H', content: '空将汉月出宫门,忆君清泪如铅水' },
            { identifier: 'I', content: '空将汉月出宫门,忆君清泪如铅水' },
          ],
        },
        {
          title: '2.单选题(8分)',
          idProp: 'questionId',
          code: 'single_choice',
          choices: [
            { identifier: 'A', content: '茂陵刘郎秋风客,夜闻马嘶晓无迹' },
            { identifier: 'B', content: '画栏桂树悬秋香,三十六宫土花碧' },
            { identifier: 'C', content: '魏官牵车指千里,东关酸风射眸子' },
            { identifier: 'D', content: '空将汉月出宫门,忆君清泪如铅水' },
          ],
        },
        {
          title: '3.单选题(8分)',
          idProp: 'questionId',
          code: 'single_choice',
          choices: [
            { identifier: 'A', content: '茂陵刘郎秋风客,夜闻马嘶晓无迹' },
            { identifier: 'B', content: '画栏桂树悬秋香,三十六宫土花碧' },
            { identifier: 'C', content: '魏官牵车指千里,东关酸风射眸子' },
            { identifier: 'D', content: '空将汉月出宫门,忆君清泪如铅水' },
          ],
        },
        {
          title: '4.单选题(8分)',
          idProp: 'questionId',
          code: 'single_choice',
          choices: [
            { identifier: 'A', content: '茂陵刘郎秋风客,夜闻马嘶晓无迹' },
            { identifier: 'B', content: '画栏桂树悬秋香,三十六宫土花碧' },
            { identifier: 'C', content: '魏官牵车指千里,东关酸风射眸子' },
            { identifier: 'D', content: '空将汉月出宫门,忆君清泪如铅水' },
            { identifier: 'E', content: '茂陵刘郎秋风客,夜闻马嘶晓无迹' },
            { identifier: 'F', content: '画栏桂树悬秋香,三十六宫土花碧' },
            { identifier: 'G', content: '魏官牵车指千里,东关酸风射眸子' },
            { identifier: 'H', content: '空将汉月出宫门,忆君清泪如铅水' },
            { identifier: 'I', content: '空将汉月出宫门,忆君清泪如铅水' },
          ],
        },]

vue组件代码:

<!--
 * @Description: 选择题(单选、多选)、判断题
-->
<template>
  <div
    :class="[
      'ac-sweep__choice',
      showBorder && 'is-border',
      isShowBorderBottom && 'is-border-bottom',
    ]"
  >
    <template v-if="Array.isArray(listData)">
      <div v-for="(item, index) in listData" :key="index">
        <ul :class="['ac-sweep__choice-box']">
          <li
            v-for="(_item, _index) in item"
            :key="`${index}_${_index}`"
            class="ac-sweep__choice-each"
          >
            {{ getBeforeChinese(_item.title) }}
            <div class="ac-sweep__choice-item">
              <span
                v-for="(__item, __index) in _item.choices"
                :key="`${index}_${_index}_${__index}`"
                class="ac-sweep__choice-option"
              >
                {{ __item.identifier }}
              </span>
            </div>
          </li>
        </ul>
      </div>
    </template>
    <template v-else>
      <ul class="ac-sweep__choice-box">
        <li>
          {{ getBeforeChinese(list.title) }}
          <div class="ac-sweep__choice-item">
            <span
              v-for="(_item, _index) in list.choices"
              :key="_index"
              class="ac-sweep__choice-option"
            >
              {{ _item.identifier }}
            </span>
          </div>
        </li>
      </ul>
    </template>
  </div>
</template>

<script>
export default {
  name: 'AcSweepChoice',
  components: {},
  props: {
    list: {
      // 此处的类型为什么不统一?原因还是<ac-card>组件中transformTree函数所致,Array类型说明是连续的单选多选判断,Object类型说明这是个单个的单选、多选、判断
      type: [Array, Object],
    },
    // 是否展示边框
    showBorder: {
      type: Boolean,
      default: true,
    },
    // 是否展示下边框
    isShowBorderBottom: {
      type: Boolean,
      default: false,
    },
  },
  computed: {
    layout() {
      return this.$store.getters['AC/layout']
    },
  },
  watch: {},
  mounted() {
    this.convertTree(this.list)
  },
  data() {
    return {
      listData: null,
    }
  },
  methods: {
    getBeforeChinese(str) {
      const chineseReg = /[\u4e00-\u9fa5]/ // 匹配汉字的正则表达式
      if (str) {
        const index = str.search(chineseReg) // 查找第一个汉字的位置
        if (index === -1) {
          return str // 如果没有汉字,则返回原字符串
        } else {
          return str.slice(0, index) // 截取汉字之前的内容
        }
      }
    },

    /**
     * @method convertTree
     * @param questions
     * @Description 此处承接<ac-card>组件中transformTree函数,之前在<ac-card>的transformTree函数中处理了将连续的单选多选判断放到一个数组中,那么下方的函数就是处理是否是连续的单选、多选或是判断了(这里的话如果是单独的单选、多选或是判断,是自身单独一个数组)。
     */
    convertTree(questions) {
      if (Array.isArray(questions)) {
        // 创建空数组用于存储分组后的题目
        const groupedQuestions = []

        // 遍历题目数组
        for (let i = 0; i < questions.length; i++) {
          const currentQuestion = questions[i]

          // 检查当前题目的类型
          if (currentQuestion.code === 'single_choice') {
            // 如果当前题目是单选
            // 检查上一个题目的类型是否与当前题目相同
            if (i === 0 || questions[i - 1].code !== 'single_choice') {
              // 如果上一个题目的类型与当前题目不同,创建新的分组数组
              groupedQuestions.push([])
            }
            // 将当前题目添加到最后一个分组数组中
            groupedQuestions[groupedQuestions.length - 1].push(currentQuestion)
          } else if (currentQuestion.code === 'multiple_choice') {
            // 如果当前题目是多选
            // 检查上一个题目的类型是否与当前题目相同
            if (i === 0 || questions[i - 1].code !== 'multiple_choice') {
              // 如果上一个题目的类型与当前题目不同,创建新的分组数组
              groupedQuestions.push([])
            }
            // 将当前题目添加到最后一个分组数组中
            groupedQuestions[groupedQuestions.length - 1].push(currentQuestion)
          } else if (currentQuestion.code === 'judgment') {
            // 如果当前题目是判断
            // 检查上一个题目的类型是否与当前题目相同
            if (i === 0 || questions[i - 1].code !== 'judgment') {
              // 如果上一个题目的类型与当前题目不同,创建新的分组数组
              groupedQuestions.push([])
            }
            // 将当前题目添加到最后一个分组数组中
            groupedQuestions[groupedQuestions.length - 1].push(currentQuestion)
          }
        }
        this.listData = groupedQuestions
      }
    },
  },
}
</script>

<style scoped lang="scss"></style>

样式代码:

.ac-sweep__choice {
  width:866px;
  padding: 20px 0px;
}
.is-border {
  border: 1px solid #000000;
  border-bottom: none;
}
.is-border-bottom {
  border-bottom: 1px solid #000000;
}
.ac-sweep__choice-box {
  display: grid;
  justify-items: flex-start;
  grid-auto-flow: column;
  // grid-template-columns: repeat(auto-fill, minmax(103px, 318px));
  // grid-template-columns: repeat(auto-fill, minmax(min-content, auto));
  // grid-template-rows: repeat(2, 20px);
  padding: 9px 32px;
  li {
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 12px;
    margin-right: 28px;
    &:last-child {
      margin-right: 0px;
    }
  }
}
.ac-sweep__choice-item {
  display: inline-flex;
  padding-left: 11px;
  .ac-sweep__choice-option {
    position: relative;
    width: 22px;
    height: 12px;
    line-height: 12px;
    margin: 4px 8px 4px 0px;
    text-align: center;
    font-family: PingFangSC-Regular;
    font-size: $--ac-font-size-small;
    &:last-child {
      margin-right: 0px;
    }
  }

  .ac-sweep__choice-option::after,
  .ac-sweep__choice-option::before {
    position: absolute;
    top: 0px;
    width: 5px;
  }

  .ac-sweep__choice-option::before {
    content: '[';
    left: 0;
  }

  .ac-sweep__choice-option::after {
    content: ']';
    right: 0;
  }
}

共有1个答案

熊烨
2023-06-22

image.png
image.png

{ column: 5,direction: "横向",}
// 横向纵向数据
    handleList(list) {
      return list.reduce((acc, cur, index, arr) => {
        cur.index = index;
        if (this.direction == "横向") {
          (acc[index % this.column ? acc.length - 1 : acc.length] ||= []).push(cur);
        } else if (this.direction == "纵向") {
          (acc[index % Math.ceil(arr.length / this.column)] ||= []).push(cur);
        }
        return acc;
      }, []);

https://codepen.io/15678871232/pen/JjeRXrg

 类似资料:
  • 本文向大家介绍一行JavaScript代码如何实现瀑布流布局,包括了一行JavaScript代码如何实现瀑布流布局的使用技巧和注意事项,需要的朋友参考一下 写在前面 一行 JavaScript 代码究竟可以完成什么布局?今天我们就来用一行 JavaScript 代码完成经典布局的一种,瀑布流布局。 所谓的瀑布流布局就是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动

  • 想问下这种样式怎么实现

  • 柱形图,当该值为0时,加最小高度,然后改造成图中的样式。单纯添加最小高度会贴着轴线而不是居中 有大佬给一下解决思路吗?

  • https://vscode.dev/,想在项目里实现这种类似功能,但是我的需求是打开本地的一个文件,可以把文件内容渲染到页面上,然后修改文件的内容,并且可以保存,他这个vscode官网就可以做到这个效果,把本地文件打开然后修改里面的内容,然后本地的文件也就被修改了,但是这个只能打开.html这种类型的文件,有办法可以连doc那种的也可以吗?有没有大佬的代码可以看一下,比较萌新