前端JS数组指针prev、current、next的实现方式,涉及是否删除当前元素的情况分析
<h1 id="背景">背景</h1><p>由于业务,需要做一个循环切换的轮播图效果,循环展示列表中的每个item,但是由于切换(从左往右移动,遇到末尾则跳到开头)的过程中可能会删掉当前元素,所以需要更新下标后再切换。由于涉及到几个临界条件,这里列出来处理方式,以便后续参考。</p>
<h1 id="情况分析">情况分析</h1>
<p>一共有两大类:<code>保留</code>(不删除当前元素,直接更新指针),<code>不保留</code>(删除这个元素,更新list,然后根据规则进行更新指针)</p>
<h2 id="1-不保留当前项">1. 不保留当前项</h2>
<p>splice后,数组长度更新了,有以下的情况:</p>
<ol>
<li><strong>新列表长度为1</strong>:那么让<code>current</code>为0,<code>prev</code>和<code>next</code>为null即可。</li>
<li><strong>新列表长度为2</strong>:<code>prev</code> 指向1,<code>current</code> 设置为0,<code>next</code> 为 <code>null</code>。</li>
<li><strong>新列表长度为3</strong>:<code>prev</code> 为2,<code>current</code> 为0,<code>next</code> 为1。<strong>(这个不写也可以,按照第四种的情况进行处理也是这个结果)</strong></li>
<li><strong>新列表长度大于3</strong>:<br>
41. <strong>current位于list头部</strong>:<code>current</code> 不变仍为<code>0</code>,<code>prev</code> 为 <code>list.length - 1</code>,如果 <code>next</code> 的值与 <code>新的prev</code> 一样,则 <code>next</code> 为 <code>null</code>。<br>
42. <strong>current位于list中间</strong>:<code>current</code> 和 <code>next</code> 移动到下一位,<code>prev</code>不变,如果新的 <code>next</code> 和 <code>prev </code>一样,则 <code>next</code> 为 <code>null</code>。<br>
43. <strong>current位于list尾部</strong>:<code>current</code> 为 <code>list.length - 1</code>,<code>prev</code> 为<code>原prev值 - 1</code>,如果 <code>next</code> 的值和 <code>新的prev</code> 一样,则 <code>next</code> 为 <code>null</code>。</li>
</ol>
<h2 id="2-保留当前项">2. 保留当前项</h2>
<p>数组长度没变化,那么有下面的情况:</p>
<ol>
<li><strong>列表长度为1</strong>:那么让<code>current</code>为0,<code>prev</code>和<code>next</code>为null即可。</li>
<li><strong>列表长度为2</strong>:切换顺序,<code>prev</code> 和 <code>current</code> 对调,<code>next</code> 为 <code>null</code>。</li>
<li><strong>列表长度大于2</strong>:
<ul>
<li><code>prev</code>: 变为 <code>原current</code> 的值;</li>
<li><code>current</code>: 变为 <code>原next</code> 的值;</li>
<li><code>next</code>:<code>原next值 + 1</code> 后是否触达数组末尾,若是则设为 <code>0</code>,不是则设为 <code>原next值 + 1</code>。</li>
</ul>
</li>
</ol>
<h1 id="代码">代码</h1>
<p>这里给出的简化过后的代码:</p>
<pre><code class="language-JAVASCRIPT"><template>
<el-switch v-model="isHold" label="保留"></el-switch>
<el-button @click="handleIndexSwitch()">切换</el-button>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { getListApi } from "@/api/list";
const isHold = ref(false); // 页面里面有个开关,是否在切换后删除当前item
const list = ref([]);
const currentItem = ref();
const INDEX = ref({
prev: null,
current: null,
next: null,
});
onMounted(() => {
getList();
});
function getList() {
getListApi().then((res) => {
let result = res.data.data;
// 初始化下标
switch (result.length) {
case 1:
INDEX.value = {
prev: null,
current: 0,
next: null,
};
break;
case 2:
INDEX.value = {
prev: 1,
current: 0,
next: null,
};
break;
default:
INDEX.value = {
prev: result.length - 1,
current: 0,
next: 1,
};
break;
}
list.value = result;
currentItem.value = result;
});
}
/**
* 处理请求列表的切换 (保留|不保留)
*/
function handleIndexSwitch() {
if (!list.value.length) return;
/** 不保留,则把当前的item删掉,然后重新计算prev、current和next的指针指向 */
if (!isHold.value) {
// 删除当前项
list.value.splice(INDEX.value.current, 1);
if (list.value.length === 0) {
currentItem.value = null;
getList();
return;
}
switch (list.value.length) {
case 1:
INDEX.value = {
prev: null,
current: 0,
next: null,
};
break;
case 2:
INDEX.value = {
prev: 1,
current: 0,
next: null,
};
break;
case 3:
INDEX.value = {
prev: 2,
current: 0,
next: 1,
};
break;
default:
if (INDEX.value.current === 0) {
INDEX.value = {
prev: list.value.length - 1,
current: 0,
next: 1,
};
} else if (INDEX.value.current === list.value.length - 1) {
INDEX.value = {
prev: INDEX.value.prev - 1,
current: list.value.length - 1,
next: INDEX.value.prev,
};
} else {
INDEX.value = {
prev: INDEX.value.prev,
current: INDEX.value.next,
next:
INDEX.value.next + 1 === list.value.length
? 0
: INDEX.value.next + 1,
};
}
break;
}
} else {
/** 保留,则切换下一个 */
switch (list.value.length) {
case 1:
INDEX.value = {
prev: null,
current: 0,
next: null,
};
break;
case 2:
/** 调换一下顺序? */
INDEX.value = {
prev: INDEX.value.current,
current: INDEX.value.prev,
next: null,
};
break;
default:
INDEX.value = {
prev: INDEX.value.current,
current: INDEX.value.next,
next:
INDEX.value.next + 1 === list.value.length
? 0
: INDEX.value.next + 1,
};
break;
}
}
currentItem.value = list.value;
isHold.value = true;
}
</script>
</code></pre><br><br>
来源:https://www.cnblogs.com/crispyChicken/p/18439077
頁:
[1]