使用vue-router+iview二次封裝一個(gè)標(biāo)簽組件

你好

不知道說(shuō)什么開(kāi)頭了,還是不說(shuō)開(kāi)頭了。直接步入主題吧。

首先判斷是否有tag,如果沒(méi)有則默認(rèn)隱藏

computed:{
  showTags(){
    return this.tagsList.length>0;
  }
}

我的思路是監(jiān)聽(tīng)route的變化狀態(tài),由此來(lái)去重添加到標(biāo)簽里

//tags.vue
watch: {
      //監(jiān)聽(tīng)路由
    $route(newValue, oldValue) {
      //當(dāng)所有tags被刪除,默認(rèn)path為/,并清空tagsList
         if(newValue.fullpath == "/"){
             this.tagsList = [];
             return;
         }
      //切換路由時(shí),默認(rèn)選中tag
      this.tagsList.some(item => {
        if (item.path === newValue.fullPath) {
          this.tagName = item.path;
        }
      });
      this.setTags(newValue);
    },

添加到標(biāo)簽里首先得判斷是否重復(fù)添加,所以得先判斷一下是否當(dāng)前跳轉(zhuǎn)過(guò)去的路由是否在tagsList已存在

methods:{
  setTags(route){
    const isExit = this.tagsList.some(item => {
      return item.path  === route.fullPath;
    });
  }
}

如果跳轉(zhuǎn)過(guò)去的路由在tagsList里面不存在的話即可添加

methods:{} 我就不寫(xiě)了
setTags(route){
  const isExit = this.tagsList.some(item => {
    return item.path === route.fullPath;
  });
  if(!isExit){
    this.tagsList.push({
      path: route.fullPath,
      meta: route.meta,
      name: route.name,
    });
  //獲取路由路徑,方便用戶知道當(dāng)前展示的是哪個(gè)界面
  this.tagName = route.fullPath;
  }
}

使用iview的tab組件綁定菜單

<template>
  <div v-if="showTags">
    <Tabs type="card" :value="tagName" @on-click="routerLink" @on-tab-remove="closeTags" closable>
      <TabPane
        v-for="item of tagsList"
        :key="item.name"
        :name="item.path"
        :label="item.name"
      ></TabPane>
    </Tabs>
  </div>
</template>

給tab綁定點(diǎn)擊跳轉(zhuǎn)事件

//頁(yè)面跳轉(zhuǎn)
routerLink(name){
  //name是獲取到你當(dāng)前點(diǎn)擊的標(biāo)簽的name值
  //跳轉(zhuǎn)頁(yè)面
  this.$router.push({ path: name });
}

給tab綁定關(guān)閉界面
注意,關(guān)閉頁(yè)面的時(shí)候得注意一下,如果是關(guān)閉當(dāng)前選中的頁(yè)面則要默認(rèn)選中當(dāng)前標(biāo)簽的最后一個(gè)標(biāo)簽
如果最后一個(gè)標(biāo)簽沒(méi)有,則展示默認(rèn)界面

//關(guān)閉頁(yè)面
closeTags(name){
  let _this = this;
  _this.tagsList.forEach((item, index) => {
      //刪除對(duì)應(yīng)的tag
      if (item.path == name) {
        _this.tagsList.splice(index, 1);
      }
    });
    //關(guān)閉當(dāng)前tag時(shí) 默認(rèn)打開(kāi)上一個(gè)tag
    if (_this.tagName === name) {
      if(_this.tagName.length>=1){
          _this.tagName = _this.tagsList[_this.tagsList.length - 1].path;
      }else{
          //如果List的長(zhǎng)度小于1 則代表關(guān)閉的是最后一個(gè),默認(rèn)展示初始界面
          _this.tagName = "/"
      }
    }
}

最后附上完整代碼和成品圖

成品展示

  <style scoped>
</style>

<template>
  <div v-if="showTags">
    <Tabs type="card" :value="tagName" @on-click="routerLink" @on-tab-remove="closeTags" closable>
      <TabPane
        v-for="item of tagsList"
        :key="item.name"
        :name="item.path"
        :label="item.name"
      ></TabPane>
    </Tabs>
  </div>
</template>

<script scoped>
export default {
  data() {
    return {
      tagsList: [],
      tagName: ""
    };
  },
  components: {},
  watch: {
      //監(jiān)聽(tīng)路由
    $route(newValue, oldValue) {
      //當(dāng)所有tags被刪除,默認(rèn)path為/
      //   if(newValue.fullpath == "/"){
      //       this.tagsList = [];
      //       return;
      //   }
      //切換路由時(shí),默認(rèn)選中tag
      this.tagsList.some(item => {
        if (item.path === newValue.fullPath) {
          this.tagName = item.path;
        }
      });
      this.setTags(newValue);
    },
    //關(guān)閉tag時(shí)切換頁(yè)面
    tagName(newValue, oldValue) {
      this.$router.push({ path: newValue });
    }
  },
  methods: {
    setTags(route) {
      //路由變換時(shí) 去重
      const isExit = this.tagsList.some(item => {
        return item.path === route.fullPath;
      });
      //當(dāng)沒(méi)有重復(fù)的時(shí)候則添加
      if (!isExit) {
        this.tagsList.push({
          path: route.fullPath,
          meta: route.meta,
          name: route.name
        });
        this.tagName = route.fullPath;
      }
    },
    //頁(yè)面跳轉(zhuǎn)
    routerLink(name) {
      this.$router.push({ path: name });
    },
    //關(guān)閉tags
    closeTags(name) {
      let _this = this;
      _this.tagsList.forEach((item, index) => {
          //刪除對(duì)應(yīng)的tag
        if (item.path == name) {
          _this.tagsList.splice(index, 1);
        }
      });
      //關(guān)閉當(dāng)前tag時(shí) 默認(rèn)打開(kāi)上一個(gè)tag
      if (_this.tagName === name) {
        if(_this.tagName.length>=1){
            _this.tagName = _this.tagsList[_this.tagsList.length - 1].path;
        }else{
            //如果List的長(zhǎng)度小于1 則代表關(guān)閉的是最后一個(gè),默認(rèn)展示初始界面
            _this.tagName = "/"
        }
      }
    }
  },
  computed: {
      //如果沒(méi)有一個(gè)tag則隱藏tag
    showTags() {
      return this.tagsList.length > 0;
    }
  }
};
</script>

使用只需要將此組件引入父組件即可(還有一點(diǎn)小bug,就是沒(méi)有使用keep-alive保存緩存,等之后我會(huì)補(bǔ)充的)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容