初识Vue-生命周期函数(详解如何让组件在不同阶段执行相应操作)

发布于:2024-05-07 ⋅ 阅读:(21) ⋅ 点赞:(0)

目录

一、生命周期介绍

1. 概念

2. 特点

3. 功能

4. 常用生命周期函数及其用法

5. 应用场景

二、生命周期语法

1. beforeCreate

2. created

3. beforeMount

4. mounted

5. beforeUpdate

6. updated

7. beforeDestroy

8. destroyed

 三、生命周期应用实例

1.计时器组件

2.博客应用文章列表和文章详情页面

3.购物车

四、总结


一、生命周期介绍

1. 概念

生命周期函数是在Vue组件生命周期中的特定时间点执行的函数。Vue实例有一个完整的生命周期,从创建、挂载、更新到销毁。在这个过程中,Vue提供了一系列的钩子函数,让你能够在特定阶段执行自定义逻辑。

2. 特点

  • 生命周期函数是一组特定的函数,它们按照特定的顺序在组件的生命周期中被调用。
  • 这些函数允许你在组件的不同阶段添加自定义逻辑,例如在组件创建前进行初始化,或在组件销毁后进行清理工作。
  • 生命周期函数的执行顺序是确定的,你可以依靠它们来确保你的逻辑按照预期的顺序执行。

3. 功能

  • 初始化: 在组件实例初始化时执行一些操作。
  • 渲染: 在组件渲染过程中执行一些操作,例如在数据更新时重新渲染。
  • 销毁: 在组件销毁时执行一些清理操作,例如移除事件监听器或取消订阅。

4. 常用生命周期函数及其用法

  • beforeCreate: 在实例初始化之后,数据观测和事件/watcher事件配置之前被调用。常用于初始化数据或在实例初始化之前执行一些异步操作。
  • created: 在实例创建完成后被立即调用。常用于数据初始化、获取异步数据等操作。
  • beforeMount: 在挂载开始之前被调用。常用于在模板编译完成后,但在挂载之前执行一些操作。
  • mounted: 实例被挂载后调用。常用于获取DOM元素、初始化第三方库等操作。
  • beforeUpdate: 数据更新时调用,发生在虚拟DOM重新渲染和打补丁之前。常用于在数据更新前执行一些操作。
  • updated: 虚拟DOM重新渲染和打补丁后调用。常用于在数据更新后执行一些DOM操作。
  • beforeDestroy: 实例销毁之前调用。常用于执行一些清理操作,如取消定时器或清理订阅。
  • destroyed: 实例销毁后调用。常用于执行一些销毁操作,如释放资源或取消事件监听器。

5. 应用场景

  • 数据初始化:created生命周期函数中初始化数据。
  • DOM操作:mounted生命周期函数中执行DOM操作,如获取元素、绑定事件等。
  • 数据更新:beforeUpdate生命周期函数中执行数据更新前的操作,如更新计算属性或进行异步操作。
  • 清理操作:beforeDestroy生命周期函数中执行清理操作,如取消定时器、清理订阅等。

二、生命周期语法

1. beforeCreate

  • 作用: 在实例初始化之后,数据观测和事件/watcher事件配置之前被调用。此时实例已经初始化,但是数据观测和事件/watcher事件尚未初始化。
  • 用途: 在这个阶段可以进行一些初始化的操作,但无法访问实例中的数据和方法。

2. created

  • 作用: 在实例创建完成后被立即调用。此时实例已经完成了数据观测、属性和方法的运算,但是尚未挂载到DOM中。
  • 用途: 常用于数据的初始化、获取异步数据、初始化实例中的数据等操作。

3. beforeMount

  • 作用: 在挂载开始之前被调用。此时模板编译已完成,但是尚未将编译好的模板挂载到DOM中。
  • 用途: 可以在此阶段进行一些DOM操作,如修改模板结构或获取DOM元素。

4. mounted

  • 作用: 实例被挂载后调用。此时实例已经挂载到了DOM中,可以访问到DOM元素。
  • 用途: 常用于获取DOM元素、初始化第三方库、发送网络请求等操作。

5. beforeUpdate

  • 作用: 数据更新时调用,发生在虚拟DOM重新渲染和打补丁之前。
  • 用途: 可以在数据更新前执行一些操作,例如更新计算属性或进行异步操作。

6. updated

  • 作用: 虚拟DOM重新渲染和打补丁后调用。
  • 用途: 常用于在数据更新后执行一些DOM操作,例如更新DOM元素的样式或内容。

7. beforeDestroy

  • 作用: 实例销毁之前调用。
  • 用途: 可以在此阶段执行一些清理操作,如取消定时器、清理订阅等。

8. destroyed

  • 作用: 实例销毁后调用。
  • 用途: 常用于执行一些销毁操作,如释放资源或取消事件监听器。
Vue.component('my-component', {
  beforeCreate() {
    // 在实例初始化之后,数据观测和事件/watcher事件配置之前被调用
    // 可以在这里进行初始化操作
  },
  created() {
    // 在实例创建完成后被立即调用
    // 可以在这里进行数据初始化、获取异步数据等操作
  },
  beforeMount() {
    // 在挂载开始之前被调用
    // 可以在模板编译完成后,但在挂载之前执行一些操作
  },
  mounted() {
    // 实例被挂载后调用
    // 可以在这里获取DOM元素、初始化第三方库等操作
  },
  beforeUpdate() {
    // 数据更新时调用,发生在虚拟DOM重新渲染和打补丁之前
    // 可以在这里执行数据更新前的操作
  },
  updated() {
    // 虚拟DOM重新渲染和打补丁后调用
    // 可以在这里执行数据更新后的DOM操作
  },
  beforeDestroy() {
    // 实例销毁之前调用
    // 可以在这里执行一些清理操作,如取消定时器或清理订阅
  },
  destroyed() {
    // 实例销毁后调用
    // 可以在这里执行一些销毁操作,如释放资源或取消事件监听器
  }
})

 三、生命周期应用实例

1.计时器组件

当组件挂载时开始计时,当组件销毁时停止计时。

<!-- Timer.vue -->
<template>
  <div>
    <p>计时器: {{ timer }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      timer: 0,
      intervalId: null
    };
  },
  mounted() {
    // 在组件挂载后开始计时
    this.intervalId = setInterval(() => {
      this.timer++;
    }, 1000);
  },
  beforeDestroy() {
    // 在组件销毁前停止计时
    clearInterval(this.intervalId);
  }
};
</script>

使用了 mounted 钩子函数来在组件挂载后开始计时,使用了 beforeDestroy 钩子函数来在组件销毁前停止计时。这样,我们就能够在组件的生命周期中添加自定义逻辑,实现了一个简单的计时器功能。

2.博客应用文章列表和文章详情页面

<!-- BlogList.vue -->
<template>
  <div>
    <h2>文章列表</h2>
    <ul>
      <li v-for="post in posts" :key="post.id" @click="showPost(post.id)">
        {{ post.title }}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      posts: []
    };
  },
  mounted() {
    // 在组件挂载后请求文章列表数据
    this.fetchPosts();
  },
  methods: {
    fetchPosts() {
      // 模拟向服务器请求文章列表数据
      setTimeout(() => {
        this.posts = [
          { id: 1, title: '文章1' },
          { id: 2, title: '文章2' },
          { id: 3, title: '文章3' }
        ];
      }, 1000);
    },
    showPost(postId) {
      // 跳转到文章详情页面
      this.$router.push(`/post/${postId}`);
    }
  }
};
</script>
<!-- BlogPost.vue -->
<template>
  <div>
    <h2>文章详情</h2>
    <p>{{ post.title }}</p>
    <p>{{ post.content }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      post: {}
    };
  },
  mounted() {
    // 在组件挂载后请求文章详情数据
    this.fetchPost(this.$route.params.postId);
  },
  methods: {
    fetchPost(postId) {
      // 模拟向服务器请求单篇文章的详细内容
      setTimeout(() => {
        this.post = {
          id: postId,
          title: `文章${postId}`,
          content: `这是文章${postId}的内容。`
        };
      }, 1000);
    }
  }
};
</script>

3.购物车

首先是商品列表组件:

<!-- ProductList.vue -->
<template>
  <div>
    <h2>商品列表</h2>
    <ul>
      <li v-for="product in products" :key="product.id">
        {{ product.name }} - ¥{{ product.price }}
        <button @click="addToCart(product)">加入购物车</button>
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      products: [
        { id: 1, name: '商品1', price: 100 },
        { id: 2, name: '商品2', price: 200 },
        { id: 3, name: '商品3', price: 150 }
      ]
    };
  },
  methods: {
    addToCart(product) {
      this.$emit('add-to-cart', product);
    }
  }
};
</script>

然后是购物车组件:

<!-- ShoppingCart.vue -->
<template>
  <div>
    <h2>购物车</h2>
    <ul>
      <li v-for="item in cart" :key="item.product.id">
        {{ item.product.name }} - 数量: {{ item.quantity }} - 总价: ¥{{ item.totalPrice }}
        <button @click="removeFromCart(item.product)">移除</button>
      </li>
    </ul>
    <p>总计: ¥{{ total }}</p>
    <button @click="checkout">结算</button>
  </div>
</template>

<script>
export default {
  props: {
    cart: {
      type: Array,
      default: () => []
    }
  },
  computed: {
    total() {
      return this.cart.reduce((acc, item) => acc + item.totalPrice, 0);
    }
  },
  methods: {
    removeFromCart(product) {
      this.$emit('remove-from-cart', product);
    },
    checkout() {
      // 结算逻辑
      alert('结算成功!请付款。');
    }
  }
};
</script>

最后是根组件,用于组合商品列表和购物车:

<!-- App.vue -->
<template>
  <div>
    <product-list @add-to-cart="addToCart"></product-list>
    <shopping-cart :cart="cart" @remove-from-cart="removeFromCart"></shopping-cart>
  </div>
</template>

<script>
import ProductList from './components/ProductList.vue';
import ShoppingCart from './components/ShoppingCart.vue';

export default {
  components: {
    ProductList,
    ShoppingCart
  },
  data() {
    return {
      cart: []
    };
  },
  methods: {
    addToCart(product) {
      const existingItem = this.cart.find(item => item.product.id === product.id);
      if (existingItem) {
        existingItem.quantity++;
      } else {
        this.cart.push({ product: product, quantity: 1, totalPrice: product.price });
      }
    },
    removeFromCart(product) {
      const index = this.cart.findIndex(item => item.product.id === product.id);
      if (index !== -1) {
        this.cart.splice(index, 1);
      }
    }
  }
};
</script>

四、总结

生命周期函数是在Vue组件实例化、挂载、更新、销毁等不同阶段触发的钩子函数,用于执行特定的操作。以下是Vue.js中常见的生命周期函数及其作用:

  1. beforeCreate: 在实例初始化之后,数据观测 (data observer) 和事件配置 (event/watcher setup) 之前被调用。在这个阶段,组件实例的选项对象已经被处理,但实例的数据和方法尚未初始化。

  2. created: 在实例创建完成后被立即调用。在这个阶段,实例已经完成了数据观测 (data observer),属性和方法的运算,但尚未挂载到DOM上。

  3. beforeMount: 在挂载开始之前被调用:相关的 render 函数首次被调用。

  4. mounted: 在挂载完成后被调用:相关的 render 函数已经创建并且挂载到DOM中。实例已经挂载到DOM上,可以访问到DOM节点。

  5. beforeUpdate: 在数据更新之前被调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,但是不会触发附加的重新渲染过程。

  6. updated: 在数据更改导致的重新渲染完成后调用。该钩子函数被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。

  7. beforeDestroy: 在实例销毁之前调用。在这个阶段,实例仍然完全可用。

  8. destroyed: 在实例销毁之后调用。在这个阶段,Vue.js 实例指示的所有东西都被解绑定,所有事件监听器和子实例被移除。

这些生命周期函数使得开发者可以在不同的阶段执行特定的逻辑,例如在组件挂载时请求数据、在销毁时清理定时器等。