记录vue3+ts项目中数组删除元素时通过splice的问题

众所周知,js的数组可以通过splice删除,但是当索引变化的时候,删除会因为索引变化没有之前的索引,删除会发生问题

// 如果我要遍历一个数组,判断当这个数组里面的某一项的if条件满足时,就删除该元素
httpServiceTableData.value.forEach((v, idx) => {
        if (v.valueAddId === valueAddId && v.source === '订单明细' && v.batchCode === 
  batchCode) {
           httpServiceTableData.value.splice(idx,1)
     }
})

结果发现用splice删除后,由于影响了原数组,导致数组length发生变化,所以idx取不到之前的值

解决办法:

使用 delete 数组[下标]来实现删除功能

httpServiceTableData.value.forEach((v, idx) => {
       if (v.valueAddId === valueAddId && v.source === '订单明细' && v.batchCode ===         
      batchCode) {
            delete httpServiceTableData.value[idx]
      }
 })

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面我来讲一下如何在 Vue3 + TypeScript 项目实现动态增减标签页并跳转到相应页面的操作。 首先,在 Vue3 实现动态标签页与上面的回答类似,需要创建一个 `tabs` 数组来存储标签页信息,并使用动态组件来加载对应的页面组件。 不过,在 TypeScript ,我们需要对 `tabs` 数组进行类型定义。我们可以定义一个 `Tab` 接口来描述标签页的结构: ```typescript interface Tab { title: string; path: string; component: any; // 动态组件类型为 any } ``` 其,`title` 表示标签页的标题,`path` 表示标签页跳转的路由路径,`component` 表示对应的页面组件,由于是动态加载的组件,因此类型为 `any`。 接着,在 Vue 组件,我们需要使用 `ref` 来创建 `tabs` 和 `currentTab` 变量,并对其进行类型定义: ```typescript import { defineComponent, ref } from 'vue'; export default defineComponent({ name: 'Tabs', setup() { const tabs = ref<Tab[]>([]); const currentTab = ref<Tab>(); // ... }, }); ``` 在此示例,我们使用了泛型 `Tab[]` 来对 `tabs` 数组进行类型定义,并使用 `Tab` 对象对 `currentTab` 进行类型定义。 接下来,我们需要实现标签页增加、删除和跳转的逻辑。这里我们可以定义以下方法: ```typescript const addTab = (tab: Tab) => { const index = tabs.value.findIndex((item) => item.path === tab.path); if (index === -1) { tabs.value.push(tab); currentTab.value = tab; } else { currentTab.value = tabs.value[index]; } }; const removeTab = (tab: Tab) => { const index = tabs.value.findIndex((item) => item.path === tab.path); if (index !== -1) { tabs.value.splice(index, 1); if (currentTab.value === tab) { currentTab.value = tabs.value[index] || tabs.value[index - 1]; } } }; const switchTab = (tab: Tab) => { currentTab.value = tab; }; ``` 其,`addTab` 方法用于增加一个标签页,如果 `tabs` 数组不存在对应的标签页,则新增一个标签页,并将 `currentTab` 设置为新增的标签页;否则直接将 `currentTab` 设置为已存在的标签页。 `removeTab` 方法用于删除一个标签页,如果 `tabs` 数组存在对应的标签页,则从 `tabs` 数组移除该标签页,并将 `currentTab` 设置为上一个或下一个标签页(如果当前标签页是第一个或最后一个标签页,则将 `currentTab` 设置为上一个或下一个标签页,否则将 `currentTab` 设置为第一个标签页)。 `switchTab` 方法用于切换到指定的标签页,将 `currentTab` 设置为指定的标签页。 最后,在模板,我们可以使用 `v-for` 循环渲染 `tabs` 数组,并使用 `router-link` 实现标签页跳转: ```html <template> <div class="tabs"> <ul> <li v-for="tab in tabs" :key="tab.path" :class="{ active: currentTab === tab }"> <router-link :to="tab.path" exact @click.native="switchTab(tab)">{{ tab.title }}</router-link> <span class="close" @click="removeTab(tab)">x</span> </li> </ul> <router-view /> </div> </template> ``` 在此模板,我们使用 `v-for` 循环渲染 `tabs` 数组,并使用 `router-link` 实现标签页跳转。在点击 `router-link` ,我们调用 `switchTab` 方法切换到对应的标签页,并设置 `router-link` 的 `exact` 属性,使得在当前标签页,`router-link` 也能被激活。 完整的代码如下: ```typescript <template> <div class="tabs"> <ul> <li v-for="tab in tabs" :key="tab.path" :class="{ active: currentTab === tab }"> <router-link :to="tab.path" exact @click.native="switchTab(tab)">{{ tab.title }}</router-link> <span class="close" @click="removeTab(tab)">x</span> </li> </ul> <router-view /> </div> </template> <script lang="ts"> import { defineComponent, ref } from 'vue'; import { RouteRecordRaw, useRoute, useRouter } from 'vue-router'; interface Tab { title: string; path: string; component: any; } export default defineComponent({ name: 'Tabs', setup() { const tabs = ref<Tab[]>([]); const currentTab = ref<Tab>(); const route = useRoute(); const router = useRouter(); const addTab = (tab: Tab) => { const index = tabs.value.findIndex((item) => item.path === tab.path); if (index === -1) { tabs.value.push(tab); currentTab.value = tab; } else { currentTab.value = tabs.value[index]; } }; const removeTab = (tab: Tab) => { const index = tabs.value.findIndex((item) => item.path === tab.path); if (index !== -1) { tabs.value.splice(index, 1); if (currentTab.value === tab) { currentTab.value = tabs.value[index] || tabs.value[index - 1]; } } }; const switchTab = (tab: Tab) => { currentTab.value = tab; router.push(tab.path); }; const findTabByPath = (path: string) => { return tabs.value.find((tab) => tab.path === path); }; const createRouteTabs = (routes: RouteRecordRaw[]) => { routes.forEach((route) => { if (route.meta?.showInTabs) { addTab({ title: route.meta.title || route.name || '', path: route.path, component: route.component || {}, }); } if (route.children) { createRouteTabs(route.children); } }); }; createRouteTabs(router.getRoutes()); const created = () => { const tab = findTabByPath(route.path); if (tab) { currentTab.value = tab; } else { const { meta, name, path, component } = route; addTab({ title: meta.title || name || '', path, component: component || {}, }); } }; return { tabs, currentTab, addTab, removeTab, switchTab, created, }; }, }); </script> ``` 在此示例,我们还使用了 `useRoute` 和 `useRouter` 钩子来获取当前路由信息和路由实例,从而实现了在页面刷新恢复标签页状态的功能。同,我们也通过 `meta` 字段来标记哪些路由需要在标签页显示。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值