移动端vant 弹框中包含tab页,记第一个tab,不加载数据问题

点击项目流程图,弹出弹框,包含tab页。爷组件>父组件>子组件

爷:

 父组件:

子组件:

代码段

爷组件:

<template>
  <div>
    <div class="project-process" @click="changeCardShowStatus">
      <img src="" />
    </div>
    <!-- 项目流程管理 -->
    <project-process-management ref="projectProcessManagement" />
  </div>
</template>

export default {
  methods: {
    changeCardShowStatus() {
      this.$refs.projectProcessManagement.projectProcessShow = true
    },
  }
}

父组件:

<template>
  <div>
    <van-popup
      v-model="projectProcessShow"
      position="bottom"
      :lock-scroll="true"
      :style="{ height: '500px' }"
      :closeable="true"
      class="process-table-popup"
      round
    >
      <div class="process-table-title">项目流程图</div>
      <div class="device-tab">
        <van-tabs class="project-tab" v-model="activeName" @click="onTabClick">
          <van-tab title="实验进度" name="testSchedule">
            <test-schedule ref="testSchedule" />
          </van-tab>
          <van-tab class="project-tab" title="基础信息" name="basicInfo">
            <basic-info ref="basicInfo" />
          </van-tab>
          <van-tab class="project-tab" title="人员信息" name="peopleInfo">
            <people-info ref="peopleInfo" />
          </van-tab>
          <van-tab class="project-tab" title="测试项目" name="testProject">
            <test-project ref="testProject" />
          </van-tab>
          <van-tab class="project-tab" title="主要节点" name="mainNode">
            <main-node ref="mainNode" />
          </van-tab>
        </van-tabs>
      </div>
    </van-popup>
  </div>
</template>

<script>
import testSchedule from "./components/testSchedule.vue";
import testProject from "./components/testProject.vue";
import peopleInfo from "./components/peopleInfo.vue";
import mainNode from "./components/mainNode.vue";
import basicInfo from "./components/basicInfo.vue";
export default {
  components: {
    testSchedule,
    testProject,
    mainNode,
    basicInfo,
    peopleInfo,
  },
  data() {
    return {
      projectProcessShow: false,
      activeName: this.$store.state.deviceTab,
    };
  },
  created() {
    if (
      ![
        "testSchedule",
        "testProject",
        "peopleInfo",
        "mainNode",
        "basicInfo",
      ].includes(this.$store.state.deviceTab)
    ) {
      this.$store.commit("SET_DEVICE_TAB", "testSchedule")
    }
  },
  mounted() { },
  watch: { },
  methods: {
    onTabClick(name, title) {
      this.$nextTick( () => {
        this.$refs[name].getList()
      }) 
      this.$store.commit("SET_DEVICE_TAB", name);
    },
  },
};
</script>


<style lang="less">
.project-tab > .van-tabs__wrap {
  width: 100vw;
  height: 44px;
  // position: fixed;
  left: 0;
  top: 100px;
  z-index: 99;
}
.project-tab > .van-tabs__wrap > .van-tabs__nav > .van-tab--active {
  font-weight: 600;
  color: #323233;
}
.project-tab .van-tab {
  font-weight: 400;
  color: #666666;
}
.project-tab .van-tabs__line {
  background: #4381f1;
  border-radius: 2px;
}

.process-table-popup {
  overflow: auto;
  .process-table-title {
    width: 100%;
    text-align: center;
    font-size: 16px;
    font-family: PingFangSC-Medium, PingFang SC;
    font-weight: 500;
    color: #333333;
    margin: 16px 0 0 0;
  }
}
</style>

子组件:

<template>
  <div>   
      <div class="schcontain">
        <div class="scheduletag">
          <div class="tagitem">
            <div class="tag" style="background:#ffc000" />
            <span class="tagtext">11</span>
          </div>
          <div class="tagitem">
            <div class="tag" style="background:#99639d" />
            <span class="tagtext">22</span>
          </div>
          <div class="tagitem">
            <div class="tag" style="background:#feded4" />
            <span class="tagtext">33</span>
          </div>
        </div>
      </div>
      <div class="process-table-content">
        <table @scroll="scrollEvent">
          <thead :class="{'box-shadow': showBoxShadow}">
            <th>序号</th>
            <th>项目(区段)名称</th>
            <th>一月</th>
            <th>一月</th>
          </thead>
          <tbody>
            <tr v-for="(item, index) in list" :key="index">
              <td>{{ index + 1 }}</td>
              <td>{{ item.projectName }}</td>
              <td class="date-cell">
                <div class="month">
                  <div v-for="num in januaryDays" :key="num" class="day">
                      <div class="tip-wrapper">
                        <div
                        class="tip-card"
                        v-show="getDayContent(item.createYear, '1', num, index).testTrainColorArray[0]"
                        :style="{width:'100%',background: '#' + getDayContent(item.createYear, '1', num, index).testTrainColorArray[0] }"
                        ></div>
                        <div
                        class="tip-card"
                        v-show="getDayContent(item.createYear, '1', num, index).testTrainColorArray[1]"
                        :style="{width:'100%',background: '#' + getDayContent(item.createYear, '1', num, index).testTrainColorArray[1] }"
                        ></div>
                        <div
                        class="tip-card"
                        v-show="getDayContent(item.createYear, '1', num, index).testTrainColorArray[2]"
                        :style="{width:'100%',background: '#' + getDayContent(item.createYear, '1', num, index).testTrainColorArray[2] }"
                        ></div>
                      </div>
                  </div>
                </div>
              </td>
              <td class="date-cell">
                <div class="month">
                  <div v-for="num in nextYearJDays" :key="num" class="day">
                      <div class="tip-wrapper">
                        <div
                        class="tip-card"
                        v-show="getDayContent(item.createYear + 1, '1', num, index).testTrainColorArray[0]"
                        :style="{width:'100%',background: '#' + getDayContent(item.createYear + 1, '1', num, index).testTrainColorArray[0] }"
                        ></div>
                        <div
                        class="tip-card"
                        v-show="getDayContent(item.createYear + 1, '1', num, index).testTrainColorArray[1]"
                        :style="{width:'100%',background: '#' + getDayContent(item.createYear + 1, '1', num, index).testTrainColorArray[1] }"
                        ></div>
                        <div
                        class="tip-card"
                        v-show="getDayContent(item.createYear + 1, '1', num, index).testTrainColorArray[2]"
                        :style="{width:'100%',background: '#' + getDayContent(item.createYear + 1, '1', num, index).testTrainColorArray[2] }"
                        ></div>
                      </div>
                  </div>
                </div>
              </td>
            </tr>
          </tbody>
          <tfoot>
            <th>合计</th>
            <th>{{ countObj.projectName }}</th>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
          </tfoot>
        </table>
      </div>
    
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import { findProjectSummarizeList } from '@/api/project.js'
export default {
  data() {
    return {
      projectProcessShow: false,
      list: [],
      countObj: {},
      januaryDays: 31, // new Date(new Date().getFullYear(), 1, 0).getDate(), // 一月
      februaryDays: new Date(new Date().getFullYear(), 2, 0).getDate(), // 二月
      marchDays: 31, // new Date(new Date().getFullYear(), 3, 0).getDate(), // 三月
      aprilDays: 30, // new Date(new Date().getFullYear(), 4, 0).getDate(), // 四月
      mayDays: 31, // new Date(new Date().getFullYear(), 5, 0).getDate(), // 五月
      juneDays: 30, // new Date(new Date().getFullYear(), 6, 0).getDate(), // 六月
      julyDays: 31, // new Date(new Date().getFullYear(), 7, 0).getDate(), // 七月
      augustDays: 31, // new Date(new Date().getFullYear(), 8, 0).getDate(), // 八月
      septemberDays: 30, // new Date(new Date().getFullYear(), 9, 0).getDate(), // 九月
      octoberDays: 31, // new Date(new Date().getFullYear(), 10, 0).getDate(), // 十月
      novemberDays: 30, // new Date(new Date().getFullYear(), 11, 0).getDate(), // 十一月
      decemberDays: 31, // new Date(new Date().getFullYear(), 12, 0).getDate(), // 十二月
      nextYearJDays: 31, // new Date(new Date().getFullYear() + 1, 1, 0).getDate(), // 下一年一月
      showBoxShadow: false
    }
  },
  computed: {
    ...mapGetters([
      'year'
    ])
  },
  created() {
    this.getList()
  },
  methods: {
    getList() {
      let year = this.year
      if (year === '所有') {
        year = ''
      }
      findProjectSummarizeList({ year: year, tabType: "1" }).then(res => {
        if (res.code === 200) {
          if (res.data.length > 0) {
            // 合计行返回到了列表的最后一个元素,因为有些字段与列表不同,所以自定义了合计行
            // 需要删除列表中的合计行,以免重复显示
            this.countObj = res.data[res.data.length - 1]
            res.data.splice(res.data.length - 1, 1)
          }
          this.list = res.data
        }
      })
    },

    getDayContent(year, month, day, index) {
      if (month < 10){
        month = '0' + month
      }
      if (day < 10) {
        day = '0' + day
      }
      let date = year + '-' + month + '-' + day
      let dateData = this.list[index].testProgress.find(item => {
        return item.planDate === date
      })
      if (dateData && dateData.testTrainColorArray.length) {
        return dateData
      }else {
        return {
          planDate: day + '日',
          testTrainColorArray: []
        }
      }
    },

    scrollEvent() {
      const tbody = this.$el.querySelector('table')
      if (tbody.scrollLeft > 0) {
        this.showBoxShadow = true
      } else {
        this.showBoxShadow = false
      }
    }
  }
}
</script>

<style lang="less" scoped>
.project-process {
  width: 100%;
  margin: 10px 0;
  height: 69px;

  img {
    padding: 0 16px;
  }
}
.process-table-popup {
  overflow: auto;
  .process-table-title {
    width: 100%;
    text-align: center;
    font-size: 16px;
    font-family: PingFangSC-Medium, PingFang SC;
    font-weight: 500;
    color: #333333;
    margin: 16px 0;
  }

  .schcontain {
    // padding: 0px 22px ;
    box-sizing: border-box;
    background: #ffffff;
    // color: #EBEDF0;;
    font-size: 8px;
    .scheduletag {
      box-sizing: border-box;
      display: flex;
      justify-content: center;
      .tagitem {
        display: flex;
        align-items: center;
        margin-right: 15px;
        .tag {
          width: 24px;
          height: 12px;
          margin-right: 5px;
          border-radius: 4px;
        }
      }
    }
  }

  .process-table-content {
    width: 100%;
    height: calc(100vh - 220px);
    table {
      width: 100%;
      height: 100%;
      display: flex;
      table-layout: fixed;
      overflow: auto;
      scroll-snap-type: x mandatory;
      thead {
        display: block;
        float: left;
        position: sticky;
        left: 0;
        z-index: 2;
        th {
          font-size: 12px;
          font-family: PingFangSC-Regular, PingFang SC;
          font-weight: 400;
          color: #666666;
          width: 33vw;
          padding: 3px 0;
          display: block;
          text-align: center;
          height: 60px;
          line-height: 60px;
          background: #F1F3F8;
          // background: #FFFFFF;
          border-top: 1px solid #EBEDF0;
          border-right: 1px solid #EBEDF0;
          z-index: 2;
        }
        // th:first-child {
        //   background: #f1f3f8;
        // }
        th:last-child {
          border-bottom: 1px solid #EBEDF0;
        }
      }
      .box-shadow {
        th {
          box-shadow: 2px 10px 10px rgba(0, 0, 0, .12);
        }
      }
      tbody {
        display: flex;
        float: left;
        background: #FFFFFF;
        tr td {
          font-size: 12px;
          font-family: PingFangSC-Regular, PingFang SC;
          font-weight: 400;
          color: #666666;
          width: 67vw;
          padding: 3px 0;
          display: block;
          text-align: center;
          height: 60px;
          line-height: 60px;
          border-top: 1px solid #EBEDF0;
          border-left: 1px solid #EBEDF0;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
          scroll-snap-align: end;

          .van-icon {
            font-size: 16px;
          }
        }
        tr:first-child td {
          border-left: 0;
        }
        tr td:last-child {
          border-bottom: 1px solid #EBEDF0;
        }

        tr .date-cell {
          padding: 0;
          .month {
            height: 100%;
            width: 100%;
            display: flex;

            .day {
              flex: 1;
              height: 60px;
              border-right: 1px solid #dfe6ec;
            }
            .tip-wrapper {
              display: flex;
              flex-direction: column;
              height: 60px;

              .tip-card {
                  flex: 1;
              }
            }
            .day:last-child {
              border-right: 0;
            }
            .today {
              background: red;
            }
            .weituo {
              background: rgb(0, 176, 240);
            }
            .dagang {
              background: rgb(146, 208, 80);
            }
            .qidonghui {
              background: rgb(255, 0, 0);
            }
            .lieche {
              background: rgb(0, 176, 80);
            }
            .dongyan {
              background: rgb(255, 192, 0);
            }
            .kaitong {
              background: rgb(112, 48, 160);
            }
          }
        }

        tr {
          td:first-child {
            background: #f1f3f8;
          }
        }
      }

      tfoot {
        display: block;
        float: left;
        background: #FFFFFF;
        th {
          font-size: 12px;
          font-family: PingFangSC-Regular, PingFang SC;
          font-weight: 400;
          color: #666666;
          width: 33vw;
          padding: 3px 0;
          display: block;
          text-align: center;
          height: 60px;
          line-height: 60px;
          border-left: 1px solid #EBEDF0;
          border-top: 1px solid #EBEDF0;
          scroll-snap-align: end;
        }
        th:first-child {
          background: #f1f3f8;
        }
        th:last-child {
          border-bottom: 1px solid #EBEDF0;
        }
      }
      
      // 隐藏滚动条
      &::-webkit-scrollbar {
        display: none;
      }
    }
  }
}
</style>

vuex:

import Vue from 'vue'
import Vuex from 'vuex'
import router from '@/router'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    deviceTab: '',
  },
  mutations: {
    //线路信息
    SET_DEVICE_TAB: (state, tabName) => {
      state.deviceTab = tabName;
    },
  },
  actions: {
  },
})

export default store

这是修改完的,可以运行起来的代码。

简述下小插曲:

1、因为第一个页签是默认加载,在父组件的created中进行了判断,但是一直获取不到第一个子组件的请求方法。后来发现问题是没有在第一个子组件中的created中自动调取获取数据的方法。加上就可以了。

2、使用ref操作或者说切换dom的显示隐藏,我一般使用v-if

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值