亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

如何利用Vue3+Element?Plus實現(xiàn)動態(tài)標(biāo)簽頁及右鍵菜單

 更新時間:2022年11月15日 08:51:26   作者:YanaDH  
標(biāo)簽頁一般配合菜單實現(xiàn),當(dāng)你點擊一級菜單或者二級菜單時,可以增加對應(yīng)的標(biāo)簽頁,當(dāng)你點擊對應(yīng)的標(biāo)簽頁,可以觸發(fā)對應(yīng)的一級菜單或者二級菜單,下面這篇文章主要給大家介紹了關(guān)于如何利用Vue3+Element?Plus實現(xiàn)動態(tài)標(biāo)簽頁及右鍵菜單的相關(guān)資料,需要的朋友可以參考下

1 前言

1.1 目的

Tabs 動態(tài)標(biāo)簽頁實現(xiàn)右鍵菜單【關(guān)閉當(dāng)前標(biāo)簽頁】、【關(guān)閉左側(cè)標(biāo)簽頁】、【關(guān)閉右側(cè)標(biāo)簽頁】、【關(guān)閉其他標(biāo)簽頁】、【關(guān)閉全部標(biāo)簽頁】功能

1.2 普通右鍵菜單

網(wǎng)上使用比較多的是v-contextmenu插件實現(xiàn)右鍵菜單,但該插件對于v-for循環(huán)生成的元素失效,插件內(nèi)部右鍵菜單顯示執(zhí)行的是emit('show')未傳入當(dāng)前元素節(jié)點(可能后續(xù)會修復(fù)),且樣式需要自行修改

1.3 本文右鍵菜單方式

本文使用element-plus自帶的el-dropdown實現(xiàn)右鍵菜單

2 生成動態(tài)標(biāo)簽頁

2.1 準(zhǔn)備變量容器

<script setup lang="ts">
import { ref } from 'vue'
interface TabType {
  title: string //標(biāo)簽頁顯示名稱
  componentName: string //動態(tài)組件名
  data: any //動態(tài)組件傳參
}
interface TabListType extends TabType {
  name: string //標(biāo)簽頁唯一標(biāo)識,添加標(biāo)簽頁時根據(jù) componentName 自動生成
}
const tabList = ref<TabListType[]>([]) //存放標(biāo)簽頁數(shù)組
const tabValue = ref('home') //存放當(dāng)前激活標(biāo)簽頁,默認(rèn)激活首頁
</script>

2.2 構(gòu)造標(biāo)簽頁

  • 可動態(tài)添加標(biāo)簽頁
  • 除【首頁】外,可動態(tài)移除標(biāo)簽頁
<template>
  <el-tabs v-model="tabValue" type="card" @tab-remove="removeTab">
    <el-tab-pane label="首頁" name="home">
      <Home />
    </el-tab-pane>
    <el-tab-pane v-for="item in tabList" :name="item.name" :key="item.name" closable>
      <component :is="item.componentName" v-bind="item.data">
      </component>
    </el-tab-pane>
  </el-tabs>
</template>

2.3 動態(tài)添加標(biāo)簽頁

const addTab = (tab: TabType) => {
   //保證相同組件路徑標(biāo)簽頁 name 標(biāo)識唯一
  const name = `${tab.componentName}_${Date.now()}`
  tabList.value.push({
    ...tab,
    name
  })
  tabValue.value = name
}

addTab({
  title: '標(biāo)簽1',
  componentName: 'tag1',
  data: {
    test: '這是測試數(shù)據(jù)'
  }
})

2.4 動態(tài)移除標(biāo)簽頁

const removeTab = (targetName: string) => {
  const index = tabList.value.findIndex((item) => item.name === targetName)
  tabList.value.splice(index, 1)
  //當(dāng)前激活標(biāo)簽頁與觸發(fā)右鍵菜單標(biāo)簽頁是同一頁
  if (targetName === tabValue.value) {
    //當(dāng)前激活標(biāo)簽頁是標(biāo)簽頁數(shù)組的第一個,則將激活標(biāo)簽頁設(shè)置為 home
    //當(dāng)前激活標(biāo)簽頁不是標(biāo)簽頁數(shù)組的第一個,則將激活標(biāo)簽頁設(shè)置為當(dāng)前激活標(biāo)簽頁的前一頁
    tabValue.value = index === 0 ? 'home' : tabList.value[index - 1].name
  }
}

removeTab('tag1')

3 生成右鍵菜單

3.1 擴(kuò)展標(biāo)簽頁

<template>
  <el-tabs v-model="tabValue" type="card" @tab-remove="removeTab">
    <el-tab-pane label="首頁" name="home">
      <Home />
    </el-tab-pane>
    <el-tab-pane v-for="item in tabList" :name="item.name" :key="item.name" closable>
      <!-- 右鍵菜單開始:自定義標(biāo)簽頁顯示名稱,保證每個標(biāo)簽頁都能實現(xiàn)右鍵菜單 -->
      <template #label>
        <el-dropdown
          trigger="contextmenu"
          :id="item.name"
          @visible-change="handleChange($event, item.name)"
          ref="dropdownRef"
        >
          <span :class="tabValue === item.name ? 'label' : ''">{{ item.title }}</span>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item @click="removeTab(item.name)">
                <el-icon><Close /></el-icon>關(guān)閉當(dāng)前標(biāo)簽頁
              </el-dropdown-item>
              <el-dropdown-item
                @click="removeTab(item.name, 'left')"
                v-if="show(item.name, 'left')"
              >
                <el-icon><DArrowLeft /></el-icon>關(guān)閉左側(cè)標(biāo)簽頁
              </el-dropdown-item>
              <el-dropdown-item
                @click="removeTab(item.name, 'right')"
                v-if="show(item.name, 'right')"
              >
                <el-icon><DArrowRight /></el-icon>關(guān)閉右側(cè)標(biāo)簽頁
              </el-dropdown-item>
              <el-dropdown-item
                @click="removeTab(item.name, 'other')"
                v-if="tabList.length > 1"
              >
                <el-icon><Operation /></el-icon>關(guān)閉其他標(biāo)簽頁
              </el-dropdown-item>
              <el-dropdown-item @click="removeTab(item.name, 'all')">
                <el-icon><Minus /></el-icon>關(guān)閉全部標(biāo)簽頁
              </el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
      </template>
      <!-- 右鍵菜單結(jié)束 -->
      <component :is="item.componentName" v-bind="item.data">
      </component>
    </el-tab-pane>
  </el-tabs>
</template>

3.2 增加 show 方法

  • 觸發(fā)右鍵菜單標(biāo)簽頁為第一個時,不展示【關(guān)閉左側(cè)標(biāo)簽頁】
  • 觸發(fā)右鍵菜單標(biāo)簽頁為最后一個時,不展示【關(guān)閉右側(cè)標(biāo)簽頁】
const show = (name: string, type: string) => {
  const index = tabList.value.findIndex((item) => name === item.name)
  return type === 'left' ? index !== 0 : index !== tabList.value.length - 1
}

3.3 擴(kuò)展 removeTab 方法

const removeTab = (targetName: string, type?: string) => {
  const index = tabList.value.findIndex((item) => item.name === targetName) //查找觸發(fā)右鍵菜單所在標(biāo)簽頁index
  const currentIndex = tabList.value.findIndex((item) => item.name === tabValue.value) //查找當(dāng)前激活標(biāo)簽頁index,存在當(dāng)前激活標(biāo)簽頁與觸發(fā)右鍵菜單標(biāo)簽頁不是同一個的情況
  switch (type) {
    case 'all': //關(guān)閉全部標(biāo)簽頁
      tabList.value = [] //清空除【首頁】外所有標(biāo)簽頁
      tabValue.value = 'home' //修改標(biāo)簽激活頁
      break
    case 'other': //關(guān)閉其他標(biāo)簽頁
      tabList.value = [tabList.value[index]]
      if (targetName !== tabValue.value) {
        tabValue.value = targetName
      }
      break
    case 'left': //關(guān)閉左側(cè)標(biāo)簽頁
      tabList.value.splice(0, index)
      if (currentIndex < index) {
        tabValue.value = targetName
      }
      break
    case 'right': //關(guān)閉右側(cè)標(biāo)簽頁
      tabList.value.splice(index + 1)
      if (currentIndex > index) {
        tabValue.value = targetName
      }
      break
    default: //默認(rèn)關(guān)閉當(dāng)前標(biāo)簽頁
      tabList.value.splice(index, 1)
      //當(dāng)前激活標(biāo)簽頁與觸發(fā)右鍵菜單標(biāo)簽頁是同一頁
      if (targetName === tabValue.value) {
        //當(dāng)前激活標(biāo)簽頁是標(biāo)簽頁數(shù)組的第一個,則將激活標(biāo)簽頁設(shè)置為 home
        //當(dāng)前激活標(biāo)簽頁不是標(biāo)簽頁數(shù)組的第一個,則將激活標(biāo)簽頁設(shè)置為當(dāng)前激活標(biāo)簽頁的前一頁
        tabValue.value = index === 0 ? 'home' : tabList.value[index - 1].name
      }
      break
  }
}

3.4 解決重復(fù)出現(xiàn)菜單問題

當(dāng)連續(xù)在多個標(biāo)簽頁觸發(fā)右鍵時,會出現(xiàn)多個菜單,解決方案為:在觸發(fā)右鍵菜單后,關(guān)閉其他右鍵菜單

const dropdownRef = ref()
const handleChange = (visible: boolean, name: string) => {
  if (!visible) return
  dropdownRef.value.forEach((item: { id: string; handleClose: () => void }) => {
    if (item.id === name) return
    item.handleClose()
  })
}

3.5 解決自定義標(biāo)簽樣式問題

<style lang="scss" scoped>
.label {
  color: var(--el-color-primary); //激活標(biāo)簽頁高亮
}
:deep(.el-tabs__item) {
  &:hover {
    span {
      color: var(--el-color-primary); //鼠標(biāo)移到標(biāo)簽頁高亮
    }
  }
  .el-dropdown {
    line-height: inherit; // 統(tǒng)一標(biāo)簽頁顯示名稱行高
  }
}
</style>

總結(jié)

到此這篇關(guān)于如何利用Vue3+Element Plus實現(xiàn)動態(tài)標(biāo)簽頁及右鍵菜單的文章就介紹到這了,更多相關(guān)Vue3 Element Plus動態(tài)標(biāo)簽頁及右鍵菜單內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解.vue文件中style標(biāo)簽的幾個標(biāo)識符

    詳解.vue文件中style標(biāo)簽的幾個標(biāo)識符

    這篇文章主要介紹了詳解.vue文件中style標(biāo)簽的幾個標(biāo)識符,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • vue中各組件之間傳遞數(shù)據(jù)的方法示例

    vue中各組件之間傳遞數(shù)據(jù)的方法示例

    Vue 的組件作用域都是孤立的,不允許在子組件的模板內(nèi)直接引用父組件的數(shù)據(jù)。必須使用特定的方法才能實現(xiàn)組件之間的數(shù)據(jù)傳遞。下面這篇文章主要給大家介紹了關(guān)于vue中各組件之間傳遞數(shù)據(jù)的方法示例,需要的朋友可以參考學(xué)習(xí)。
    2017-07-07
  • 一文詳解Vue中的虛擬DOM與Diff算法

    一文詳解Vue中的虛擬DOM與Diff算法

    vue中的diff算法時常是面試過程中的考點,本文將為大家講解何為diff以及diff算法的實現(xiàn)過程,那么在了解diff之前,我們需要先了解虛擬DOM是什么,需要的朋友可以參考下
    2024-02-02
  • 詳解vue element plus多語言切換

    詳解vue element plus多語言切換

    這篇文章主要為大家介紹了vue element plus多語言切換,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • 詳解vuex中mapState,mapGetters,mapMutations,mapActions的作用

    詳解vuex中mapState,mapGetters,mapMutations,mapActions的作用

    這篇文章主要介紹了vuex中mapState,mapGetters,mapMutations,mapActions的作用,需要的朋友可以參考下
    2018-04-04
  • vue中如何獲取當(dāng)前路由地址

    vue中如何獲取當(dāng)前路由地址

    這篇文章主要介紹了vue中如何獲取當(dāng)前路由地址,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • vue實現(xiàn)button按鈕的重復(fù)點擊指令方式

    vue實現(xiàn)button按鈕的重復(fù)點擊指令方式

    這篇文章主要介紹了vue實現(xiàn)button按鈕的重復(fù)點擊指令方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 封裝一個更易用的Dialog組件過程詳解

    封裝一個更易用的Dialog組件過程詳解

    這篇文章主要為大家介紹了封裝一個更易用的Dialog組件過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • 簡單了解vue 插值表達(dá)式Mustache

    簡單了解vue 插值表達(dá)式Mustache

    這篇文章主要介紹了vue 插值表達(dá)式Mustache的相關(guān)資料,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • vue組件以及父子組件通信方式

    vue組件以及父子組件通信方式

    這篇文章主要介紹了Vue組件化的基本概念,包括什么是組件化、Vue的組件化思想以及如何在Vue中注冊和使用組件,文章還詳細(xì)講解了如何進(jìn)行父子組件之間的通信,包括父組件傳遞數(shù)據(jù)給子組件和子組件通過自定義事件將數(shù)據(jù)傳遞給父組件,文章最后通過一個綜合練習(xí)來鞏固所學(xué)知識
    2025-02-02

最新評論