vue 生命周期

最近一直在加班,都没时间学习,真的是对于vue的知识没有多少进步,昨天还在公司加班,今天抽空学习一下生命周期吧。

生命周期基本介绍

官方文档相关介绍生命周期

还是先举例子:

<template>
  <div class="app-container">
    <div>
      <h2>{{message}}</h2>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: "测试生命周期以及路由"
    };
  },
  computed: {
    route () {
      return this.$route
    }
  },
  beforeRouteEnter(to, from, next) {
    console.group("父组件beforeRouterEnter 路由进入===============》");
    console.log("%c%s", "color:red", "this     : " + this);
    next(vm => {

    });
  },
  beforeRouteUpdate(to, from, next) {
    console.group("父组件beforeRouterUpdate 路由更新===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);
    next(vm => {
    });
  },
  beforeRouteLeave(to, from, next) {
    console.group("父组件beforeRouteLeave 路由离开===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);
    next(vm => {
    });
  },
  beforeCreate() {
    console.group("父组件beforeCreate 创建前状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);

    var self = this;
    setTimeout(()=>{
      self.message = '修改父组件'
    }, 1000)
  },
  created() {
    console.group("父组件created 创建完毕状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el); //undefined
    console.log("%c%s", "color:red", "data   : " + this.$data); //已被初始化
    console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
  },
  beforeMount() {
    console.group("父组件beforeMount 挂载前状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el); //undefined
    console.log("%c%s", "color:red", "data   : " + this.$data); //已被初始化
    console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
  },
  mounted() {
    console.group("父组件mounted 挂载结束状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el); //已被初始化
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data); //已被初始化
    console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
  },
  beforeUpdate() {
    console.group("父组件beforeUpdate 更新前状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);
  },
  updated() {
    console.group("父组件updated 更新完成状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);
  },
  beforeDestroy() {
    console.group("父组件beforeDestroy 销毁前状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);
  },
  destroyed() {
    console.group("父组件destroyed 销毁完成状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);
  }
};
</script>

<style lang="scss" scoped>
</style>

进入路由页面

得到结果:

  • beforecreated:el 和 data 并未初始化 
  • created:完成了 data 数据的初始化,el没有
  • mounted :完成了 el 和 data 初始化 

离开当前路由

得到结果:

 

包含子组件的生命周期

<template>
  <div class="app-container">
    <div>
      <h2>{{message}}</h2>
      <search-condition></search-condition>
    </div>
  </div>
</template>

<script>
import SearchCondition from "./SearchCondition";
export default {
  components: {
    'search-condition': SearchCondition
  },
  data() {
    return {
      message: "测试生命周期以及路由"
    };
  },
  computed: {
    route() {
      return this.$route;
    }
  },
  beforeRouteEnter(to, from, next) {
    console.group("父组件beforeRouterEnter 路由进入===============》");
    console.log("%c%s", "color:red", "this     : " + this);
    next(vm => {});
  },
  beforeRouteUpdate(to, from, next) {
    console.group("父组件beforeRouterUpdate 路由更新===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);
    next(vm => {});
  },
  beforeRouteLeave(to, from, next) {
    console.group("父组件beforeRouteLeave 路由离开===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);
    next(vm => {});
  },
  beforeCreate() {
    console.group("父组件beforeCreate 创建前状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);

    // var self = this;
    // setTimeout(() => {
    //   self.message = "修改父组件";
    // }, 1000);
  },
  created() {
    console.group("父组件created 创建完毕状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el); //undefined
    console.log("%c%s", "color:red", "data   : " + this.$data); //已被初始化
    console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
  },
  beforeMount() {
    console.group("父组件beforeMount 挂载前状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el); //undefined
    console.log("%c%s", "color:red", "data   : " + this.$data); //已被初始化
    console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
  },
  mounted() {
    console.group("父组件mounted 挂载结束状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el); //已被初始化
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data); //已被初始化
    console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
  },
  beforeUpdate() {
    console.group("父组件beforeUpdate 更新前状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);
  },
  updated() {
    console.group("父组件updated 更新完成状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);
  },
  beforeDestroy() {
    console.group("父组件beforeDestroy 销毁前状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);
  },
  destroyed() {
    console.group("父组件destroyed 销毁完成状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);
  }
};
</script>

<style lang="scss" scoped>
</style>
<template>
  <el-card shadow="never">
    <h2>{{message}}</h2>
    <div class="search-condition">
      <!-- 查询操作 -->
      <div class="search-condition-buttons">
        <el-input v-model="filterInfo" placeholder="请输入" clearable></el-input>
      </div>
    </div>
  </el-card>
</template>

<script>
export default {
  name: "SearchCondition",
  components: {},
  data() {
    return {
      message: '子组件',
      filterInfo: ""
    };
  },
  beforeCreate() {
    console.group("子组件beforeCreate 创建前状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el); //undefined
    console.log("%c%s", "color:red", "data   : " + this.$data); //undefined
    console.log("%c%s", "color:red", "message: " + this.message);

    // var self = this;
    // setTimeout(()=>{
    //   self.message = '子组件修改'
    // }, 1000)
  },
  created() {
    console.group("子组件created 创建完毕状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el); //undefined
    console.log("%c%s", "color:red", "data   : " + this.$data); //已被初始化
    console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
  },
  beforeMount() {
    console.group("子组件beforeMount 挂载前状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el); //已被初始化
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data); //已被初始化
    console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
  },
  mounted() {
    console.group("子组件mounted 挂载结束状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el); //已被初始化
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data); //已被初始化
    console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
  },
  beforeUpdate() {
    console.group("子组件beforeUpdate 更新前状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);
  },
  updated() {
    console.group("子组件updated 更新完成状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);
  },
  beforeDestroy() {
    console.group("子组件beforeDestroy 销毁前状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);
  },
  destroyed() {
    console.group("子组件destroyed 销毁完成状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);
  },
  methods: {
    // 点击事件
    onSearchClick() {
      this.$emit("onSearchClick", this.filterInfo);
    }
  }
};
</script>
<style lang="stylus">
.el-card__body {
  padding: 0px !important;
}
</style>

<style lang="stylus" scoped>
.el-card__body {
  padding: 0px !important;
}
</style>

得到结果:

  • 子组件的创建在父组件beforeMount之后,而不是在父组件create之后
  • 父组件挂载必须在子组件挂载成功之后才会开始

父组件更新data

将父组件的setTimeout函数注释去掉

得到结果:

  • 父组件的页面重新渲染不会影响到子组件

子组件更新data

注释父组件的setTimeout,将子组件的setTimeout事主是去掉

得到结果

  • 子组件的页面重新渲染不会影响到父组件

父组件更新传递给子组件的prop

修改代码,子组件接受父组件的props

<search-condition :parentMessage="childMessage"></search-condition>

父组件在1000ms之后修改子组件的props,并且子组件接受该参数在页面显示

var self = this;
setTimeout(() => {
  self.childMessage = "修改子组件props";
}, 1000);

得到结果:此时产生两次父组件的更新,一次子组件的更新

猜测:父组件的第一次更新为父组件向子组件传递值的内容变化引起,第二次为子组件页面的重新渲染引起。为了侧面查看,我在父子组件的输出内容里,输出了子组件的parentMessage属性值。

输出结果:父组件的第二次更新为子组件渲染过程

父组件beforeUpdate 更新前状态===============》
index.vue?6c72:83 更新子组件的prop
index.vue?6c72:86 父组件updated 更新完成状态===============》
index.vue?6c72:91 更新子组件的prop
index.vue?6c72:78 父组件beforeUpdate 更新前状态===============》
index.vue?6c72:82 message: 测试生命周期以及路由
index.vue?6c72:83 更新子组件的prop
index.vue?ee1d:60 子组件beforeUpdate 更新前状态===============》
index.vue?ee1d:65 修改子组件props
index.vue?ee1d:68 子组件updated 更新完成状态===============》
index.vue?ee1d:73 修改子组件props
index.vue?6c72:86 父组件updated 更新完成状态===============》
index.vue?6c72:91 修改子组件props

问题:子路由创建数据然后跳转父路由列表,父路由上的设置依然存在

这个问题的来源为:项目开发中,碰到主页面为数据列表,带有查询条件以及分页信息,主页面可以跳转到添加页面,添加页面数据之后,跳转回到列表页面,不想之前的查询信息以及分页信息会改变。

这里需要将主列表数据页面设置成父路由,然后添加页面设置为子路由,为了在渲染子路由页面的时候父路由信息不显示,需要使用v-show进行处理,但是不能使用v-if。v-if会造成页面的重新渲染。

<template>
  <!-- 父组件 -->
  <div class="app-container">
    <div v-show="route.path ===  `/example/tree`">
      <h2>{{message}}</h2>
      <SearchCondition></SearchCondition>
      <el-table :data="tableData" style="width: 100%">
        <el-table-column prop="date" label="日期" width="180"></el-table-column>
        <el-table-column prop="name" label="姓名" width="180"></el-table-column>
        <el-table-column prop="address" label="地址"></el-table-column>
      </el-table>
        <router-link :to="`create`" append>
          <el-button type="primary" class="model-list-actions-button">
            添加
          </el-button>
        </router-link>
    </div>
    <router-view/>
  </div>
</template>

<script>
import SearchCondition from "./SearchCondition";
import "./Utils";

export default {
  components: {
    SearchCondition
  },
  data() {
    return {
      message: "测试生命周期以及路由",
      tableData: [
        {
          date: "2016-05-02",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1518 弄"
        },
        {
          date: "2016-05-04",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1517 弄"
        },
        {
          date: "2016-05-01",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1519 弄"
        },
        {
          date: "2016-05-03",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1516 弄"
        }
      ]
    };
  },
  computed: {
    route () {
      return this.$route
    }
  },
  beforeRouteEnter(to, from, next) {
    console.group("父组件beforeRouterEnter 路由进入===============》");
    console.log("%c%s", "color:red", "this     : " + this); //undefined
    next(vm => {
      //某些不可告人的操作
    });
  },
  beforeRouteUpdate(to, from, next) {
    console.group("父组件beforeRouterUpdate 路由更新===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el); //undefined
    console.log("%c%s", "color:red", "data   : " + this.$data); //undefined
    console.log("%c%s", "color:red", "message: " + this.message);
    next(vm => {
      //某些不可告人的操作
    });
  },
  beforeRouteLeave(to, from, next) {
    console.group("父组件beforeRouteLeave 路由离开===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el); //undefined
    console.log("%c%s", "color:red", "data   : " + this.$data); //undefined
    console.log("%c%s", "color:red", "message: " + this.message);
    next(vm => {
      //某些不可告人的操作
    });
  },
  beforeCreate() {
    console.group("父组件beforeCreate 创建前状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el); //undefined
    console.log("%c%s", "color:red", "data   : " + this.$data); //undefined
    console.log("%c%s", "color:red", "message: " + this.message);

    // var self = this;
    // setTimeout(()=>{
    //   self.message = '修改父组件'
    // }, 1000)
  },
  created() {
    console.group("父组件created 创建完毕状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el); //undefined
    console.log("%c%s", "color:red", "data   : " + this.$data); //已被初始化
    console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
  },
  beforeMount() {
    console.group("父组件beforeMount 挂载前状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el); //已被初始化
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data); //已被初始化
    console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
  },
  mounted() {
    console.group("父组件mounted 挂载结束状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el); //已被初始化
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data); //已被初始化
    console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
  },
  beforeUpdate() {
    console.group("父组件beforeUpdate 更新前状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);
  },
  updated() {
    console.group("父组件updated 更新完成状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);
  },
  beforeDestroy() {
    console.group("父组件beforeDestroy 销毁前状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);
  },
  destroyed() {
    console.group("父组件destroyed 销毁完成状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);
  }
};
</script>

<style lang="scss" scoped>
</style>
<template>
  <el-card shadow="never">
    <h2>{{parentMessage}}</h2>
    <div class="search-condition">
      <!-- 查询操作 -->
      <div class="search-condition-buttons">
        <el-input v-model="filterInfo" placeholder="请输入" clearable></el-input>
      </div>
    </div>
  </el-card>
</template>

<script>
export default {
  name: "SearchCondition",
  props: {
    parentMessage: {
      type: String
    } 
  },
  components: {},
  data() {
    return {
      message: '子组件',
      filterInfo: ""
    };
  },
  beforeCreate() {
    console.group("子组件beforeCreate 创建前状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el); //undefined
    console.log("%c%s", "color:red", "data   : " + this.$data); //undefined
    console.log("%c%s", "color:red", "message: " + this.message);

    // var self = this;
    // setTimeout(()=>{
    //   self.message = '子组件修改'
    // }, 1000)
  },
  created() {
    console.group("子组件created 创建完毕状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el); //undefined
    console.log("%c%s", "color:red", "data   : " + this.$data); //已被初始化
    console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
  },
  beforeMount() {
    console.group("子组件beforeMount 挂载前状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el); //undefined
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data); //已被初始化
    console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
  },
  mounted() {
    console.group("子组件mounted 挂载结束状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el); //已被初始化
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data); //已被初始化
    console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
  },
  beforeUpdate() {
    console.group("子组件beforeUpdate 更新前状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);
    console.log(this.parentMessage)
  },
  updated() {
    console.group("子组件updated 更新完成状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);
    console.log(this.parentMessage)
  },
  beforeDestroy() {
    console.group("子组件beforeDestroy 销毁前状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);
    console.log(this.parentMessage)
  },
  destroyed() {
    console.group("子组件destroyed 销毁完成状态===============》");
    console.log("%c%s", "color:red", "el     : " + this.$el);
    console.log(this.$el);
    console.log("%c%s", "color:red", "data   : " + this.$data);
    console.log("%c%s", "color:red", "message: " + this.message);
  },
  methods: {
    // 点击事件
    onSearchClick() {
      this.$emit("onSearchClick", this.filterInfo);
    }
  }
};
</script>
<style lang="stylus">
.el-card__body {
  padding: 0px !important;
}
</style>

<style lang="stylus" scoped>
.el-card__body {
  padding: 0px !important;
}
</style>

联系:从上面的生命周期可以看到当路由重新跳转到主路由的时候,会有着对应生命周期方法触发,所有对于列表数据的更新只需要在对应生命周期方法执行就可以了。

之前有看过keep-alive也有着类似的效果,还没有去研究过,后面去学习吧。希望年后回来找个好工作!

 

参照:

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页