整顿baba山-循环渲染

55 阅读2分钟

要整顿的代码

 <div class="middle">
        <div v-for="(item, column) in targetArr" class="column">
          <div v-if="column == 0" class="flex_five">
            <div class="l">
              <img src="../assets/images/five/l1.svg" alt="" />
            </div>
            <div>
              <div
                :data-column="column"
                :data-row="row"
                v-for="(sub, row) in item.current"
                class="item baseBox"
                :class="[
                  sub.type == 'manager' ? 'manager' : '',
                  sub.right && sub.name ? 'right' : 'blank',
                ]"
                v-drag
                @mouseover="(e) => isOver(e)"
                @mouseleave="(e) => isLeave(e)"
              >
                {{ sub.name }}
              </div>
            </div>
          </div>
          <div v-else-if="column == 1" class="flex_five">
            <div class="l">
              <img src="../assets/images/five/l2.svg" alt="" />
            </div>
            <div>
              <div
                :data-column="column"
                :data-row="row"
                v-for="(sub, row) in item.current"
                class="item baseBox"
                :class="[
                  sub.type == 'manager' ? 'manager' : '',
                  sub.right && sub.name ? 'right' : 'blank',
                ]"
                v-drag
                @mouseover="(e) => isOver(e)"
                @mouseleave="(e) => isLeave(e)"
              >
                {{ sub.name }}
              </div>
            </div>
          </div>
          <div v-else-if="column == 2" class="flex_five">
            <div class="l3">
              <img src="../assets/images/five/l3.svg" alt="" />
            </div>
            <div>
              <div
                :data-column="column"
                :data-row="row"
                v-for="(sub, row) in item.current"
                class="item baseBox"
                :class="[
                  sub.type == 'manager' ? 'manager' : '',
                  sub.right && sub.name ? 'right' : 'blank',
                ]"
                v-drag
                @mouseover="(e) => isOver(e)"
                @mouseleave="(e) => isLeave(e)"
              >
                {{ sub.name }}
              </div>
            </div>
          </div>
          <div v-else-if="column == 3" class="flex_five">
            <div class="l4">
              <img src="../assets/images/five/l4.svg" alt="" />
            </div>
            <div>
              <div
                :data-column="column"
                :data-row="row"
                v-for="(sub, row) in item.current"
                class="item baseBox"
                :class="[
                  sub.type == 'manager' ? 'manager' : '',
                  sub.right && sub.name ? 'right' : 'blank',
                ]"
                v-drag
                @mouseover="(e) => isOver(e)"
                @mouseleave="(e) => isLeave(e)"
              >
                {{ sub.name }}
              </div>
            </div>
          </div>
        </div>
      </div>

step1 图片路径写入数组

const imgArr = reactive(["l1.svg", "l2.svg", "l3.svg", "l4.svg"]);

step2 抽出基础结构

<div class="middle">
    <div v-for="(item, column) in targetArr" class="column">
      <div v-if="column == 0" class="flex_five"> // 1.去掉了三个一样的div盒子,后续加入循环
        <div class="l"> // 3.所以循环加在这里,并会通过column与index判断imgArr中哪张图片显示在下面div盒子前
          <img src="../assets/images/five/l1.svg" alt="" />
        </div>
        <div> //2.每个盒子这部分都是确定的
          <div
            :data-column="column"
            :data-row="row"
            v-for="(sub, row) in item.current"
            class="item baseBox"
            :class="[
              sub.type == 'manager' ? 'manager' : '',
              sub.right && sub.name ? 'right' : 'blank',
            ]"
            v-drag
            @mouseover="(e) => isOver(e)"
            @mouseleave="(e) => isLeave(e)"
          >
            {{ sub.name }}
          </div>
        </div>
      </div>
    </div>
</div>

step3 加入循环

 <div class="middle">
    <div v-for="(item, column) in targetArr" class="column">
      <div class="flex_five">
        <div class="l" v-for="(imgItem, index) in imgArr"> // 1、循环图片
          <img
            src="../assets/images/five/l1.svg" // 为方便确定结构能够显示,先使用测试路径
            alt=""
            v-if="column == index" // 2、判断
          />
        </div>
        <div>
          <div
            :data-column="column"
            :data-row="row"
            v-for="(sub, row) in item.current"
            class="item baseBox"
            :class="[
              sub.type == 'manager' ? 'manager' : '',
              sub.right && sub.name ? 'right' : 'blank',
            ]"
            v-drag
            @mouseover="(e) => isOver(e)"
            @mouseleave="(e) => isLeave(e)"
          >
            {{ sub.name }}
          </div>
        </div>
      </div>
    </div>
</div>

step4 优化

通过v-if显示与隐藏,每个div前面四个图片的位置都在,影响样式

image.png

巧妙利用column替换index

image.png

<div class="middle">
    <div v-for="(item, column) in targetArr" class="column">
      <div class="flex_five">
        <div class="l">
          <img :src="imgArr[column]" alt="" /> // 替换 循环+v-if="column == index"
        </div>
        <div>
          <div
            :data-column="column"
            :data-row="row"
            v-for="(sub, row) in item.current"
            class="item baseBox"
            :class="[
              sub.type == 'manager' ? 'manager' : '',
              sub.right && sub.name ? 'right' : 'blank',
            ]"
            v-drag
            @mouseover="(e) => isOver(e)"
            @mouseleave="(e) => isLeave(e)"
          >
            {{ sub.name }}
          </div>
        </div>
      </div>
    </div>
</div>

step5 图片显示不出来,解析出来的url不正确

项目中有getAssets需要传三个参数的情况,而这次调用只需要传两个参数 一开始想的是给第三个参数设默认值为'',这样导致解析出来的url不正确,非常疑惑

能正确显示图片的路径(乱码是因为图片名用的中文)

image.png

我碰到的解析错误的路径

image.png

解决办法

注意到undefined,所以最终解决就是又定义一个getAssets1来接收只传递两个参数的情况 image.png

function getAssets(task, name, num='') {
  return new URL(`../assets/images/${task}/${name}/${num}`, import.meta.url).href;
}
function getAssets1(task, name,) {
  return new URL(`../assets/images/${task}/${name}`, import.meta.url).href;
}
export { getAssets ,getAssets1};
<div class="middle">
    <div v-for="(item, column) in targetArr" class="column">
      <div class="flex_five">
        <div class="l">
          <img :src="getAssets1('five', imgArr[column])" alt="" />
        </div>
        <div>
          <div
            :data-column="column"
            :data-row="row"
            v-for="(sub, row) in item.current"
            class="item baseBox"
            :class="[
              sub.type == 'manager' ? 'manager' : '',
              sub.right && sub.name ? 'right' : 'blank',
            ]"
            v-drag
            @mouseover="(e) => isOver(e)"
            @mouseleave="(e) => isLeave(e)"
          >
            {{ sub.name }}
          </div>
        </div>
      </div>
    </div>
</div>

step6 调整样式

<div class="middle">
    <div v-for="(item, column) in targetArr" class="column">
      <div class="flex_five">
        <div :class="classArr[column]">
          <img :src="getAssets1('five', imgArr[column])" alt="" />
        </div>
        <div>
          <div
            :data-column="column"
            :data-row="row"
            v-for="(sub, row) in item.current"
            class="item baseBox"
            :class="[
              sub.type == 'manager' ? 'manager' : '',
              sub.right && sub.name ? 'right' : 'blank',
            ]"
            v-drag
            @mouseover="(e) => isOver(e)"
            @mouseleave="(e) => isLeave(e)"
          >
            {{ sub.name }}
          </div>
        </div>
      </div>
    </div>
</div>
const classArr = reactive(["l", "l", "l3", "l4"]);

最终代码量

<div class="middle">
    <div v-for="(item, column) in targetArr" class="column">
      <div class="flex_five">
        <div :class="classArr[column]">
          <img :src="getAssets1('five', imgArr[column])" alt="" />
        </div>
        <div>
          <div
            :data-column="column"
            :data-row="row"
            v-for="(sub, row) in item.current"
            class="item baseBox"
            :class="[
              sub.type == 'manager' ? 'manager' : '',
              sub.right && sub.name ? 'right' : 'blank',
            ]"
            v-drag
            @mouseover="(e) => isOver(e)"
            @mouseleave="(e) => isLeave(e)"
          >
            {{ sub.name }}
          </div>
        </div>
      </div>
    </div>
</div>
import { getAssets1 } from "../utils/getAssets";
const imgArr = reactive(["l1.svg", "l2.svg", "l3.svg", "l4.svg"]);
const classArr = reactive(["l", "l", "l3", "l4"]);