vue+element ui 的tab 动态增减,切换时提示用户是否切换

前言:工作中用到 vue+element ui 的前端框架,动态添加 Tab,删除 Tab,切换 Tab 时提示用户是否切换等,发现 element ui  有一个 bug,这里记录一下如何实现。转载请注明出处:https://www.cnblogs.com/yuxiaole/p/9523735.html

网站地址:我的个人vue+element ui demo网站 

github地址:yuleGH github

 

 

代码如下: 

<html>

<head>
    <title>测试</title>
    <!-- 引入样式 -->
    <link rel="stylesheet" href="../lib/elementui/theme-chalk/index.css" type="text/css">
</head>
<body>
<div id="app">
  <p style="color: red;">自定义增加标签页触发器,切换标签页时提示是否切换</p>

  <div style="margin-bottom: 20px;">
    <el-button size="small"  @click="addTab(editableTabsValue)">
      add tab
    </el-button>
  </div>
  <el-tabs v-model="editableTabsValue" type="card" closable
    @tab-remove="removeTab"
    :before-leave="beforeLeaveTab">
    <el-tab-pane
      v-for="(item, index) in editableTabs"
      :key="item.id"
      :label="'Tab' + (index + 1)"
      :name="item.id">
      {{item.content}}
    </el-tab-pane>
  </el-tabs>

</div>
<!-- 引入组件库 -->
<script type="text/javascript" src="../lib/vue.js"></script>
<script type="text/javascript" src="../lib/elementui/index.js"></script>

<script type="text/javascript">
    new Vue({
        el: "#app",
        data: {
          editableTabsValue : '1',
          editableTabs: [{
            id: '1',
            content: 'Tab 1 content'
          }, {
            id: '2',
            content: 'Tab 2 content'
          }],
          tabIndex : 2,

          isTip : true
        },
        methods: {
          addTab(targetId) {
            let newTabId = ++this.tabIndex + '';
            this.editableTabs.push({
              id: newTabId,
              content: 'New Tab content'
            });
            this.isTip = false;
            this.editableTabsValue = newTabId;
          },
          removeTab(targetId) {
            let tabs = this.editableTabs;
            let activeId = this.editableTabsValue;
            if (activeId === targetId) {
              tabs.forEach((tab, index) => {
                if (tab.id === targetId) {
                  let nextTab = tabs[index + 1] || tabs[index - 1];
                  if (nextTab) {
                    activeId = nextTab.id;
                  }
                  this.isTip = false;
                  this.editableTabsValue = activeId;
                }
              });
            }

            this.editableTabs = tabs.filter(tab => tab.id !== targetId);
          },

          beforeLeaveTab(){
            if(!this.isTip){
              this.isTip = true;
              return true;
            }

            return this.$confirm('此操作将切换tab页, 是否继续?', '提示', {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            }).then(() => {
              this.$message({
                type: 'success',
                message: '切换成功!可以做一些其他的事情'
              });
            }).catch(() => {
              this.$message({
                type: 'success',
                message: '取消成功!可以做一些其他的事情'
              });
              throw new Error("取消成功!");
            });
          }

        }
    });
</script>

</body>

</html>

完。

   

发现一个bug

  在使用 el-tabs 的属性 before-leave 时可以返回 Promise 来控制是否切换,如下:

  于是,我直接返回了 $confirm 方法返回的 Promise,

        return this.$confirm('此操作将切换tab页, 是否继续?', '提示', {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            }).then(() => {
              this.$message({
                type: 'success',
                message: '切换成功!可以做一些其他的事情'
              });
            });            

  可是当点击弹出框取消时页面报错如下:

  点击上方查看源码,发现源码如下:

  所以,发现 vue minui 封装的 promise 定义了 reject,而这里没有加取消处理,而且我们的 this.$confirm 也没有加取消方法,所以自己加上取消方法传过去就好了。

  但是只是在 this.$confirm 加取消方法,仅仅能做到不报错而已,并不能做到用户点击取消时阻止切换。

解决方案

  element ui 源码中加上如下代码 ,function(){}

  并在使用时这样使用:

          beforeLeaveTab(){
            return this.$confirm('此操作将切换tab页, 是否继续?', '提示', {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            }).then(() => {
              this.$message({
                type: 'success',
                message: '切换成功!可以做一些其他的事情'
              });
            }).catch(() => {
              this.$message({
                type: 'success',
                message: '取消成功!可以做一些其他的事情'
              });
              throw new Error("取消成功!");
            });
          }

 

转载请注明出处:https://www.cnblogs.com/yuxiaole/p/9523735.html

 

posted @ 2018-08-23 22:53  取个名字吧  阅读(24944)  评论(1编辑  收藏  举报