如何在el-tabs(标签页)中随activeName只调该页面初始化接口,而不是一进页面就调所有标签页的接口

  • Post author:
  • Post category:其他


需求:把不同的页面封成组件,再放在el-tabs里面用标签切换。

遇到的问题:因为本质上这些页面组件都同一个页面,所以会同时执行created钩子,造成性能浪费。我想点哪个组件,就执行此页面的初始化方法。(之前碰到七个标签页的crud页面,一起调会卡顿)。

解决:用this.$refs[this.activeName].init()调用组件内的初始化方法,而不是放到created。

注意:

用 this. $ nextTick(() => { this.$refs[this.activeName].init();} );来处理dom异步渲染

在这里插入图片描述

<template>
  <div>
    <el-tabs v-model="activeName" type="card" @tab-click="handleClick">
      <el-tab-pane label="按上传途径" name="upload">
        <upload ref="upload"></upload>
      </el-tab-pane>
      <el-tab-pane label="按用户类型" name="user">
        <user ref="user"></user>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>

<script>
import upload from "./upload";
import user from "./user";
export default {
  components: {
    upload,
    user
  },
  data() {
    return {
      activeName: "upload"
    };
  },
  created() {
    this.goRoute(); 
    //配上路由处理是为了给每个标签页的地址加上activeName,可以通过路由直接定位到该标签页
    this.$nextTick(() => {
      this.$refs[this.activeName].init();
    });
  },
  watch: {
    $route(n) {
      this.activeName = n.query.activeName;
      this.$refs[this.activeName].init();
    },
    activeName(n) {
      this.$router.push({
        path: "/statisticAnalysis/picStatistic/index",
        query: {
          activeName: n
        }
      });
    }
  },
  methods: {
    goRoute() {
      if (this.$route.query.activeName) {
        this.activeName = this.$route.query.activeName;
      }
    },
    handleClick(tab, event) {
      this.$refs[this.activeName].init();
    }
  }
};
</script>

如果此时this.activeName=upload,那么就是this.$ refs[this.activeName]就等于this.$refs[upload],访问的就是upload组件。

所以要在upload的组件里定义一个init()方法,一点击标签就会跳到相应组件,并且同时调用init()



upload组件里:

<template>
  <div>
    
  </div>
</template>

<script>
export default {
  data() {
    return {
     
  },
  // created() {
  //   不用生命周期函数
  // },
  methods: {
    init() {
    //想干什么就在init里写
      console.log("来到了upload组件")
    },
    }
</script>
   

简单转载一个$nextTick例子

(链接有详细讲解)

作者:Ruheng

链接:

https://www.jianshu.com/p/a7550c0e164f

先来一个示例了解下关于Vue中的DOM更新以及nextTick的作用。

模板

<div class="app">
  <div ref="msgDiv">{{msg}}</div>
  <div v-if="msg1">Message got outside $nextTick: {{msg1}}</div>
  <div v-if="msg2">Message got inside $nextTick: {{msg2}}</div>
  <div v-if="msg3">Message got outside $nextTick: {{msg3}}</div>
  <button @click="changeMsg">
    Change the Message
  </button>
</div>

Vue实例

new Vue({
  el: '.app',
  data: {
    msg: 'Hello Vue.',
    msg1: '',
    msg2: '',
    msg3: ''
  },
  methods: {
    changeMsg() {
      this.msg = "Hello world."
      this.msg1 = this.$refs.msgDiv.innerHTML
      this.$nextTick(() => {
        this.msg2 = this.$refs.msgDiv.innerHTML
      })
      this.msg3 = this.$refs.msgDiv.innerHTML
    }
  }
})

点击前

在这里插入图片描述

点击后

在这里插入图片描述

从图中可以得知:msg1和msg3显示的内容还是变换之前的,而msg2显示的内容是变换之后的。其根本原因是因为Vue中DOM更新是异步的。



版权声明:本文为ciichen原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。