欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

Vue组件的关键生命周期阶段:创建(created)、挂载(mounted)与销毁(destroyed)

最编程 2024-02-19 22:57:11
...

组件生命周期

当我们 new 一个 vue 时或者当我们创建一个组件时,会创建一个实例。比如:当我们使用<Comp />组件,就会创建一个组件实例,实例创建之后会经历以下流程:

1、 注入

把配置项里的一些成员(比如:data、computed、methods等)放到vue实例里,这个过程叫注入。注入之后完成数据响应式设置。如下图:

image.png

2、注入之后,生成虚拟DOM树

3、生成虚拟DOM树之后,进行挂载 挂载:就是生成真实的DOM到页面上。

4、随后进入已挂载状态

5、如果数据变动,会重新生成虚拟DOM树

如何生成虚拟DOM?

1)先看render,有render就执行render,不看其他的;

2)如果没有render,则看template,有template,则把它编译成render;

3)如果没有template,则看el对应的元素,把它作为模版。把el元素的outerHTML作为模版。

6、新旧两棵虚拟DOM树进行对比

7、将差异应用到真实的DOM

image.png

vue考虑到我们有可能在一个组件里的某个阶段做一些额外的事,比如:当vue实例完成注入之后,加载一些异步数据(比如:远程的api),那就需要vue给我们提供一些钩子函数(hooks)。

vue给我们提供了钩子函数,下图是vue详细的生命周期,如下图:

钩子函数写在哪儿?

直接写到配置里。如下图:

export default{
    beforeCreate(){
    }
}

image.png

钩子函数常见应用

加载远程数据

<template>
    <div>
        <ul>
            <li v-for="item in banners" :key="item.id"></li>
        </ul>
    </div>
</template>

// 需求:获取banner远程数据
import {getBanners} from '@/api/banner';

export default{
    data(){
        return {
            banners:[]
        }
    },
    created(){    
       //调用远程数据的方法,这是异步的
      getBanners().then((res)=>{
          this.banners = res;
      })
    }
    
    // 上面的方法也可以写成下面这样,效果一样
    async created(){    
      this.banners = await getBanners();
    },
    
    // 获取远程数据是异步的,不会影响组件的进行,当获取到数据之后,重新渲染,并且updated也执行。
    updated(){
        console.log('update')
    }
}

页面上直接操作DOM

<template>
  <div ref="container">
    容器宽度:{{ containerWidth }} 容器高度:{{ containerHeight }}
  </div>
</template>

<script>
export default {
  data() {
    return {
      containerWidth: 0,
      containerHeight: 0,
    };
  },
  mounted() {
    this.containerWidth = this.$refs.container.clientWidth;
    this.containerHeight = this.$refs.container.clientHeight;
  },
  updated() {
    console.log("updated");
  },
};
</script>

启动和清除定时器

<template>
  <h1>当前时间:{{ current }}</h1>
</template>

<script>
export default {
  data() {
    return {
      current: this.getCurrent(),
      timer: null,
    };
  },
  methods: {
    getCurrent() {
      return new Date().toLocaleTimeString();
    },
  },
  created() {
    console.log("created");
    this.timer = setInterval(() => {
      console.log("更新了时间");
      this.current = this.getCurrent();
    }, 1000);
  },
  destroyed() {
    clearInterval(this.timer);
  },
};