Vue:现代前端开发的首选框架-【声明周期钩子详解】

引言

Vue.js 是一个流行的前端框架,它通过组件化的开发方式,让开发者能够构建出高效且可维护的应用程序。在Vue中,生命周期钩子(Lifecycle Hooks)是理解组件行为的关键概念。本文将深入探讨Vue生命周期钩子,从创建到销毁的全过程,帮助开发者更好地掌握Vue组件的生命周期。

1. Vue生命周期概述

Vue的生命周期指的是一个Vue实例从创建到销毁的过程。在这个过程中,Vue提供了一系列的钩子函数,允许开发者在特定的时机执行代码。生命周期钩子主要分为初始化、挂载、更新和销毁四个阶段。

2. 初始化阶段的钩子

初始化阶段是Vue组件生命周期的开始,这个阶段的钩子允许开发者在组件实例化时执行代码。以下是初始化阶段的两个主要钩子:

2.1 beforeCreate 钩子

beforeCreate 钩子在Vue实例初始化之后,数据观测(data observer)和事件配置之前被调用。这意味着在这个钩子中,你还不能访问到组件的data属性,因为它们还没有被设置。但是,你可以在这个钩子中执行一些基本的初始化操作,比如初始化一些不依赖于组件数据的状态。

示例:

export default {beforeCreate() {console.log('beforeCreate: 组件实例已创建,但data和methods还未初始化。');// 可以在这里进行一些初始化操作,比如设置一些全局状态this.globalState = 'Initialized';}
}

在这个示例中,我们打印了一条消息,并且初始化了一个全局状态变量。请注意,由于datamethods还未初始化,我们不能在这里访问它们。

2.2 created 钩子

created 钩子在Vue实例创建完成后,数据观测和事件配置已经完成时调用。此时,组件的data属性和methods方法都已可用,但是组件尚未挂载到DOM上。

示例:

export default {data() {return {message: 'Hello, Vue!'};},created() {console.log('created: 组件实例已完全创建,data和methods已初始化。');console.log(this.message); // 输出: Hello, Vue!// 可以在这里访问data属性和调用methods方法this.initialize();},methods: {initialize() {// 执行一些初始化逻辑console.log('Initialization logic inside a method.');}}
}

在这个示例中,我们在created钩子中访问了data属性,并调用了一个方法。这表明在created钩子中,组件的数据和方法都已准备就绪。

2.3 应用场景

初始化阶段的钩子主要用于执行一些在组件实例化时需要完成的操作,以下是一些常见的应用场景:

  • 数据初始化:在created钩子中初始化组件的数据。
  • 事件监听:在created钩子中为组件添加事件监听器。
  • API请求:在created钩子中发起API请求,获取数据。
  • 全局状态管理:在beforeCreate钩子中设置全局状态。

2.4 注意事项

在使用初始化阶段的钩子时,需要注意以下几点:

  • 避免DOM操作:由于组件还未挂载到DOM,所以在beforeCreatecreated钩子中不应执行DOM操作。
  • 避免复杂的异步操作:尽管可以在created钩子中发起API请求,但复杂的异步操作可能会阻塞组件的渲染。考虑使用mounted钩子或观察者模式来处理这些操作。
  • 组件通信:如果你需要在多个组件之间共享状态或事件,可以在beforeCreate钩子中设置全局状态或事件总线。

3. 挂载阶段的钩子

挂载阶段是Vue组件生命周期中的关键时期,组件从虚拟DOM渲染到真实DOM,并开始与用户交互。这个阶段的钩子允许开发者在组件挂载前后执行特定的代码。以下是挂载阶段的两个主要钩子:

3.1 beforeMount 钩子

beforeMount 钩子在Vue组件挂载开始之前被调用。此时,组件的模板已经被编译成虚拟DOM,但是还没有渲染到页面上。这个钩子主要用于在组件渲染之前执行一些准备工作。

示例:

export default {data() {return {items: []};},beforeMount() {console.log('beforeMount: 模板编译完成,即将挂载到页面上。');// 可以在这里执行一些准备工作,比如发送请求获取数据this.fetchItems();},methods: {fetchItems() {// 假设这是一个获取数据的异步操作setTimeout(() => {this.items = ['Item 1', 'Item 2', 'Item 3'];}, 1000);}}
}

在这个示例中,我们在beforeMount钩子中调用了一个方法fetchItems,模拟了一个异步数据请求的过程。注意,由于组件还未挂载,所以这里不能直接看到DOM的变化。

3.2 mounted 钩子

mounted 钩子在Vue组件被挂载到DOM之后调用。此时,你可以访问到DOM元素,执行依赖于DOM的操作,如直接操作DOM或通过this.$refs访问子组件。

示例:

export default {mounted() {console.log('mounted: 组件已经挂载到页面上。');// 可以在这里执行依赖于DOM的操作this.doSomethingWithDOM();},methods: {doSomethingWithDOM() {// 例如,获取页面上某个元素的尺寸const element = this.$refs.myElement;console.log(`The element size is: ${element.offsetWidth}x${element.offsetHeight}`);}}
}

在这个示例中,我们在mounted钩子中执行了一个依赖于DOM的操作,即获取并打印了一个DOM元素的尺寸。

3.3 应用场景

挂载阶段的钩子在以下场景中非常有用:

  • 数据获取:在beforeMount中发起API请求,获取并准备渲染所需的数据。
  • DOM操作:在mounted中直接操作DOM,如设置元素的尺寸、样式或绑定事件监听器。
  • 第三方库集成:在mounted中初始化或配置第三方库,这些库可能需要访问DOM元素。
  • 组件交互:在mounted中与其他组件进行交互,如通过this.$refs访问子组件或通过事件总线与兄弟组件通信。

3.4 注意事项

在使用挂载阶段的钩子时,需要注意以下几点:

  • 避免重复渲染:在beforeMountmounted中执行的操作不应触发组件的重新渲染,因为这可能导致性能问题。
  • 异步操作:如果你在beforeMount中执行异步操作,确保在mounted钩子之前完成,以避免渲染时数据还未准备好。
  • 组件依赖:如果你需要在mounted钩子中访问其他组件,确保这些组件已经挂载。如果存在依赖顺序,可能需要使用Vue的provide/inject API。

4. 更新阶段的钩子

更新阶段是Vue组件生命周期中处理数据变化和响应式更新的关键时期。这个阶段的钩子允许开发者在组件的数据发生变化并且触发重新渲染之前和之后执行特定的代码。以下是更新阶段的两个主要钩子:

4.1 beforeUpdate 钩子

beforeUpdate 钩子在Vue组件的数据更新之前被调用。这意味着组件的虚拟DOM即将重新渲染,但实际的DOM更新还没有发生。这个钩子可以用于在数据更新前执行一些准备工作。

示例:

export default {data() {return {count: 0};},beforeUpdate() {console.log('beforeUpdate: 组件数据即将更新,但DOM还未更新。');// 可以在这里执行一些准备工作,比如记录日志或状态检查}
}

在这个示例中,我们在beforeUpdate钩子中记录了一条日志,表明组件的数据即将更新。

4.2 updated 钩子

updated 钩子在Vue组件的数据更新完成后被调用。此时,组件的虚拟DOM已经重新渲染,并且实际的DOM也已经更新。这个钩子可以用于在数据更新后执行一些操作,如执行依赖于新数据的DOM操作。

示例:

export default {data() {return {count: 0};},updated() {console.log('updated: 组件数据已经更新,DOM也已更新。');// 可以在这里执行依赖于新数据的DOM操作this.checkDOMUpdates();},methods: {increment() {this.count++;},checkDOMUpdates() {// 假设我们有一个显示计数的元素const countElement = this.$refs.countDisplay;console.log(`Count displayed in DOM: ${countElement.textContent}`);}}
}

在这个示例中,我们在updated钩子中调用了一个方法checkDOMUpdates,该方法检查并记录了DOM中显示的计数是否与数据同步更新。

4.3 应用场景

更新阶段的钩子在以下场景中非常有用:

  • 状态同步:在beforeUpdate中同步一些状态,为即将到来的DOM更新做准备。
  • 性能优化:在updated中执行一些性能优化操作,如懒加载图片或延迟加载资源。
  • 依赖于DOM的操作:在updated中执行依赖于新数据的DOM操作,如动态调整元素尺寸或重新计算布局。
  • 数据验证:在updated中进行数据验证,确保更新后的数据符合预期。

4.4 注意事项

在使用更新阶段的钩子时,需要注意以下几点:

  • 避免直接修改数据:在beforeUpdateupdated钩子中直接修改响应式数据可能导致无限循环或不可预期的行为。
  • 避免复杂的异步操作:虽然可以在updated钩子中执行异步操作,但应避免复杂的异步逻辑,因为这可能会影响组件的响应性和性能。
  • 避免DOM操作的滥用:虽然updated钩子允许执行DOM操作,但应谨慎使用,避免过度操作DOM,因为这可能导致性能问题。

5. 销毁阶段的钩子

销毁阶段是Vue组件生命周期的结束,当组件不再需要时,这个阶段的钩子允许开发者执行清理工作,确保资源得到合理释放。以下是销毁阶段的两个主要钩子:

5.1 beforeDestroy 钩子

beforeDestroy 钩子在Vue组件实例销毁之前被调用。此时,组件仍然完全可用,但即将被销毁。这个钩子是执行清理工作的最佳时机,如取消网络请求、移除事件监听器等。

示例:

export default {data() {return {timerId: null};},beforeDestroy() {console.log('beforeDestroy: 组件即将被销毁。');// 清理工作,如清除定时器if (this.timerId) {clearInterval(this.timerId);}}
}

在这个示例中,我们在beforeDestroy钩子中清除了一个定时器。这是防止内存泄漏的常见做法。

5.2 destroyed 钩子

destroyed 钩子在Vue组件实例销毁完成后被调用。此时,组件不能被再次使用,所有的数据绑定都被解除,监听器和子组件适当地被销毁。

示例:

export default {destroyed() {console.log('destroyed: 组件已经被销毁,无法再被使用。');// 可以在这里执行一些最终的清理工作this.cleanupExternalResources();},methods: {cleanupExternalResources() {// 例如,移除全局事件监听器document.removeEventListener('keydown', this.handleKeyPress);},handleKeyPress(event) {// 一些键盘事件处理逻辑}}
}

在这个示例中,我们在destroyed钩子中移除了一个全局的键盘事件监听器,这是避免内存泄漏的另一个例子。

5.3 应用场景

销毁阶段的钩子在以下场景中非常有用:

  • 资源清理:在beforeDestroy中清理定时器、动画帧、网络请求等资源。
  • 事件监听器移除:在beforeDestroy中移除组件添加的所有事件监听器。
  • 外部库清理:在destroyed中清理使用外部库时创建的资源,如图表库、地图服务等。
  • 状态重置:在beforeDestroy中重置组件的状态,为可能的重新创建做准备。

5.4 注意事项

在使用销毁阶段的钩子时,需要注意以下几点:

  • 确保组件不再使用:在beforeDestroydestroyed钩子中,组件可能已经被标记为待销毁,因此避免执行任何可能重新激活组件的操作。
  • 避免新的状态更改:在销毁钩子中,避免修改组件的状态,因为这可能导致未定义的行为。
  • 清理工作彻底:确保所有资源都被适当清理,避免内存泄漏和其他潜在问题。

6. 特殊钩子

除了标准的生命周期钩子外,Vue还提供了一些特殊的钩子,这些钩子用于处理特定的场景和高级功能。这些特殊钩子包括activateddeactivatederrorCaptured

6.1 activateddeactivated 钩子

这两个钩子与Vue Router集成时特别有用,它们允许你在组件被激活或停用时执行代码。

示例:

export default {data() {return {pageData: null};},activated() {console.log('activated: 当前组件被激活。');// 可以在这里执行一些仅当组件被激活时需要的操作this.fetchPageData();},deactivated() {console.log('deactivated: 当前组件被停用。');// 可以在这里执行一些组件停用时的清理工作this.cleanupPageData();},methods: {fetchPageData() {// 模拟数据请求setTimeout(() => {this.pageData = 'Fetched Data';}, 1000);},cleanupPageData() {// 清理数据this.pageData = null;}}
}

在这个示例中,activated 钩子用于在组件被激活时获取页面数据,而deactivated 钩子则在组件被停用时清理这些数据。

6.2 errorCaptured 钩子

errorCaptured 钩子允许你在组件中捕获子孙组件的错误。

示例:

export default {errorCaptured(error, vm, info) {console.log(`errorCaptured: 捕获到一个错误 - ${error.toString()}.`);console.log(`Error occurred in ${info}.`);// 可以在这里记录错误或执行其他错误处理逻辑this.logError(error);},methods: {logError(error) {// 记录错误到控制台或发送到错误跟踪服务console.error(error);}}
}

在这个示例中,errorCaptured 钩子用于捕获并记录子孙组件中发生的错误。

6.3 应用场景

特殊钩子在以下场景中非常有用:

  • 路由视图管理:使用activateddeactivated 钩子来管理路由视图的激活和停用状态。
  • 错误处理:使用errorCaptured 钩子来全局捕获和处理组件中的错误。
  • 性能监控:在activated 中监控组件激活的性能,优化加载时间。
  • 资源释放:在deactivated 中释放组件激活时占用的资源,如停止视频播放或取消定时器。

6.4 注意事项

在使用特殊钩子时,需要注意以下几点:

  • 路由集成activateddeactivated 钩子与Vue Router紧密集成,确保正确配置路由。
  • 错误传播:在使用errorCaptured 时,决定是否重新抛出错误,以避免隐藏错误。
  • 性能影响:避免在特殊钩子中执行重计算或高成本操作,以免影响性能。

7. 组合式API中的生命周期钩子

随着Vue 3的推出,引入了Composition API,这是一种新的编写组件逻辑的方式。组合式API提供了一套不同的生命周期钩子,它们与Vue 2的选项API中的生命周期钩子有所不同。以下是组合式API中的一些关键生命周期钩子:

7.1 setup 函数

setup 是Composition API的入口点,它在组件创建之前执行。setup 函数提供了一个上下文对象,其中包含了组件的propsemitslots等属性。

示例:

import { ref, onMounted, onUnmounted } from 'vue';export default {props: ['initialCount'],setup(props, { emit }) {const count = ref(props.initialCount);const increment = () => {count.value++;emit('update', count.value);};onMounted(() => {console.log('Component is mounted.');});onUnmounted(() => {console.log('Component is unmounted.');});return {count,increment};}
};

在这个示例中,setup 函数初始化了一个响应式状态count,并定义了一个increment 方法来更新这个状态。同时,我们使用onMountedonUnmounted来注册挂载和卸载的生命周期钩子。

7.2 onBeforeMountonMountedonBeforeUpdateonUpdatedonBeforeUnmountonUnmounted

这些函数是Composition API提供的生命周期钩子,它们允许你在setup函数内部以一种声明式的方式处理组件的生命周期事件。

示例:

import { ref, onBeforeMount, onMounted, onBeforeUpdate, onUpdated } from 'vue';export default {setup() {const data = ref(0);onBeforeMount(() => {console.log('Component is about to be mounted.');});onMounted(() => {console.log('Component has been mounted.');});onBeforeUpdate(() => {console.log('Component data is about to be updated.');});onUpdated(() => {console.log('Component data has been updated.');});return {data};}
};

在这个示例中,我们使用Composition API的生命周期钩子来记录组件在不同阶段的状态。

7.3 应用场景

组合式API的生命周期钩子在以下场景中非常有用:

  • 组件初始化:在setup中初始化组件的状态和逻辑。
  • 性能优化:使用onBeforeUpdateonUpdated来监控和优化组件的更新性能。
  • 资源管理:在onMountedonUnmounted中管理外部资源,如DOM操作、网络请求等。
  • 依赖注入:使用Composition API的provideinject函数在组件树中共享状态。

7.4 注意事项

在使用组合式API的生命周期钩子时,需要注意以下几点:

  • 响应式状态:确保在setup中声明的所有状态都是响应式的,以便Vue能够追踪变化。
  • 避免副作用setup函数本身不应该包含副作用,所有的副作用应该放在生命周期钩子中。
  • 钩子的顺序:理解不同生命周期钩子的执行顺序,以确保逻辑的正确性。

8. 生命周期钩子的最佳实践

掌握Vue生命周期钩子的最佳实践对于构建高效、可维护的应用程序至关重要。以下是一些关键的最佳实践,以及示例代码,帮助你更好地理解和应用这些概念。

8.1 避免在created钩子中执行DOM操作

由于在created钩子中,组件的DOM还未挂载,因此任何尝试访问this.$elthis.$refs的操作都将返回undefined

示例:

export default {created() {// 错误的做法:尝试访问DOM// console.log(this.$el); // 这里会是undefined// 正确的做法:如果需要访问DOM,使用mounted钩子}
};

8.2 在mounted钩子中执行DOM相关操作

mounted钩子在组件的DOM挂载完成后调用,此时可以安全地访问DOM元素。

示例:

export default {mounted() {// 正确的做法:在DOM挂载后访问DOMconsole.log(this.$el); // 现在可以访问到DOM元素this.doSomethingWithDOM();},methods: {doSomethingWithDOM() {// 执行DOM相关操作}}
};

8.3 合理使用beforeDestroydestroyed钩子进行清理

在组件销毁前和销毁后,使用beforeDestroydestroyed钩子来执行清理工作,如取消定时器、移除事件监听器等。

示例:

export default {data() {return {timerId: null};},beforeDestroy() {// 清理定时器if (this.timerId) {clearInterval(this.timerId);}},destroyed() {// 可以在这里执行其他清理工作}
};

8.4 避免在生命周期钩子中进行重计算

在生命周期钩子中执行重计算或高成本的操作可能会影响组件的性能。

示例:

export default {created() {// 错误的做法:在created钩子中执行重计算// this.computeExpensiveValue();// 正确的做法:如果需要执行重计算,考虑使用watchers或computed properties}
};

8.5 使用key属性管理动态组件的生命周期

当使用v-ifv-for来动态切换组件时,使用key属性可以帮助Vue识别哪个组件是新的,哪个组件应该被销毁。

示例:

<template><component :is="currentComponent" key="componentKey"></component>
</template>

8.6 避免在beforeRouteEnterbeforeRouteLeave中直接操作DOM

在使用Vue Router时,beforeRouteEnterbeforeRouteLeave守卫在路由进入和离开之前调用,此时组件实例尚未被创建或已经销毁,因此不能直接操作DOM。

示例:

export default {beforeRouteEnter(to, from, next) {// 错误的做法:尝试访问组件实例// console.log(this.$el); // 这里会导致错误// 正确的做法:如果需要访问组件实例,使用next回调函数next(vm => {// 现在可以安全地访问组件实例});}
};

8.7 组合式API中使用onBeforeMountonUnmounted

在Composition API中,使用onBeforeMountonUnmounted来替代Vue 2中的beforeMountdestroyed

示例:

import { ref, onBeforeMount, onUnmounted } from 'vue';export default {setup() {const data = ref(null);onBeforeMount(() => {// 在组件挂载前执行});onUnmounted(() => {// 在组件卸载后执行});return {data};}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/845763.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络故障与排除(四)

一、WLAN网络优化分为几个部分 WLAN网络进行优化时&#xff0c;可以从下面几个方面开展优化&#xff1a; 1.AP功率调整&#xff1b; 2.天馈系统调整&#xff1b; 3.AP信道调整&#xff1b; 4.干扰调整&#xff1b; 5.网络侧组网和带宽调整。 二、Portal重定向原理 1、P…

如何让Google收录网页?

确保网页被Google快速且持续地收录&#xff0c;页面的质量起着至关重要的作用。高质量的网页不仅更容易被搜索引擎收录&#xff0c;而且能够提高网页在搜索结果中的排名&#xff0c;想确保页面的质量&#xff0c;要保持原创&#xff0c;确保你的内容是独一无二的&#xff0c;别…

Python基础教程——数据类型和变量

数据类型和变量 Python使用缩进来组织代码块,一般使用4个空格的缩进.使用#来注释一行,其他每一行都是一个语句,当语句以冒号:结尾时,缩进的语句视为代码块.Python对大小写敏感. 1.1 整数 Python可以处理任意大小的整数,包括负整数,写法与数学上写法一致,例如&#xff1a;-10…

使用OpenCV进行简单图像分割的3个步骤

想象一下&#xff0c;用几行Python代码就能让你的照片中的人物“跳”出来&#xff0c;或者精准地把蓝天从背景中分离。今天&#xff0c;我们就用OpenCV这个强大的图像处理库来实现这一魔法&#xff0c;而且只需要三个简单的步骤&#xff01;让我们一起&#xff0c;把复杂的技术…

Qt Creator中, ui设计中设置属性无效, 会自动变回去问题

最近学qt遇到个问题, 很奇怪, 具体表现为: 我想修改这个字体大小为12, 但是修改后会自动变回9, 我读取qss方式设置样式, 依然无效&#xff01;找了很久&#xff0c;最终发现是我在最上层设置了字体大小&#xff0c; 导致下面的所有控件&#xff0c; 全部设置字体无效&#xff…

不常用但特别好用的字符串方法—.partitioin()和.translate()

不常用但特别好用的字符串方法—.partitioin()和.translate() 在 Python 中, str.partition() 和 str.translate() 是两种有用的字符串方法,可以帮助您以不同的方式操作字符串。 1. str.partition(sep) 该 partition() 方法使用指定的分隔符 ( sep ) 将字符串拆分为三个部…

文档分词与词汇权重(TF-IDF)

文档分词与词汇权重 1、文档分词2、词汇权重&#xff08;TF-IDF&#xff09; 1、文档分词 文本分类主要做的是如何提取文本中的主要信息。那么&#xff0c;如何衡量哪些信息是主要信息呢&#xff1f; 我们知道&#xff0c;一篇文档是由若干词汇组成的&#xff0c;也就是文档的…

Flutter 中的 SliverCrossAxisGroup 小部件:全面指南

Flutter 中的 SliverCrossAxisGroup 小部件&#xff1a;全面指南 Flutter 是一个功能丰富的 UI 开发框架&#xff0c;它允许开发者使用 Dart 语言来构建高性能、美观的移动、Web 和桌面应用。在 Flutter 的丰富组件库中&#xff0c;SliverCrossAxisGroup 是一个较少被使用的组…

【CPP】栈简介及简化模拟实现

CPP栈和队列简单模拟实现 目录 1. 栈的简介2. 栈简化模拟实现3. 栈练习题 1. 栈的简介 栈 是一种 特殊的线性表&#xff0c;具有数据 先进后出 特点。 具体参考&#xff1a;【数据结构】栈 CPP库参考文档&#xff1a;stl_stack 注意&#xff1a; 1.stack本身 不支持迭代器操…

骨传导耳机防踩雷秘诀是什么?六大选购技巧独家揭秘!

相信大家都已经深有体会&#xff0c;拿那种常规的入耳式无线蓝牙耳机来做运动耳机&#xff0c;很难满足运动需要。如果选择前两年流行的颈挂式无线运动蓝牙耳机&#xff0c;虽然简单轻巧&#xff0c;但也是入耳式设计&#xff0c;长时间佩戴耳朵不舒服。这样看来&#xff0c;运…

Python-3.12.0文档解读-内置函数sorted()详细说明+记忆策略+常用场景+巧妙用法+综合技巧

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 Python-3.12.0文档解读详细说明 功能描述 参数说明 用法示例 备注 进阶用法 参考…

【Qt】【模型视图架构】代理模型示例

文章目录 1. 基本排序/过滤模型Basic Sort/Filter Model Example2. 自定义排序/过滤模型Custom Sort/Filter Model ExampleFilterLineEdit类定义及实现MySortFilterProxyModel类定义及实现 1. 基本排序/过滤模型Basic Sort/Filter Model Example 官方提供的基本排序/过滤模型示…

docker 清理磁盘

文章目录 Docker - 解决/var/lib/docker/overlay2占用很大、容器无法启动问题&#xff08;清理磁盘&#xff09;一、首先执行如下命令可以查看 docker 文件夹磁盘使用情况&#xff1a;二、执行如下可以查看 Docker 的磁盘使用情况&#xff08;类似于 Linux 上的 df 命令&#x…

【算法】贪心算法——柠檬水找零

题解&#xff1a;柠檬水找零(贪心算法) 目录 1.题目2.题解3.参考代码4.证明5.总结 1.题目 题目链接&#xff1a;LINK 2.题解 分情况讨论 贪心算法 当顾客为5元时&#xff0c;收下当顾客为10元时&#xff0c;收下10元并找回5元当顾客为20元时&#xff0c;收下20元并找回10…

使用Python进行图像锐化的4个基础操作

想要让你的照片从模糊变锐利&#xff0c;就像魔法师轻轻一挥魔杖&#xff1f;今天我们就来学习如何用Python施加这神奇的“锐化滤镜”&#xff01;&#x1f389; 首先&#xff0c;你需要一位得力助手——Pillow库&#xff0c;它能让我们轻松处理图像。如果你还没安装&#xff…

Python Config 用法:探索配置文件的艺术

Python Config 用法&#xff1a;探索配置文件的艺术 在Python编程的广袤领域中&#xff0c;config模块以其独特的方式&#xff0c;为开发者们提供了一种灵活而强大的配置管理手段。本文将深入剖析config的用法&#xff0c;从四个方面、五个方面、六个方面和七个方面展现其魅力…

大泽动力车载柴油发电机的特点和优势有哪些

大泽动力车载柴油发电机具有一系列显著的特点和优势&#xff0c;以下是对其的详细介绍&#xff1a; 低噪音性能&#xff1a;大泽动力车载柴油发电机具备明显的低噪音性能&#xff0c;其噪音限值在距离机组7米处测得为70dB(A)&#xff0c;这为用户提供了一个相对安静的工作环境…

Java18+​App端采用uniapp+开发工具 idea hbuilder智能上门家政系统源码,一站式家政服务平台开发 家政服务(师傅端)介绍

Java18​App端采用uniapp开发工具 idea hbuilder智能上门家政系统源码&#xff0c;一站式家政服务平台开发 家政服务&#xff08;师傅端&#xff09;介绍 家政服务师傅端是一个专为家政服务人员设计的平台&#xff0c;该平台旨在提供便捷、高效的工作机会&#xff0c;同时确保…

html期末复习速览

一.基础标签 1.段落标签<p></p> 特点&#xff1a;分段分割 2.标题标签<h1></h1>……<h6></h6> 特点&#xff1a;文字加粗&#xff0c;单独占一行 3.换行标签<br /> 特点&#xff1a;单标签&#xff0c;强制换行 二.文本格式化…

View->Bitmap缩放到自定义ViewGroup的任意区域(Matrix方式绘制Bitmap)

Bitmap缩放和平移 加载一张Bitmap可能为宽高相同的正方形&#xff0c;也可能为宽高不同的矩形缩放方向可以为中心缩放&#xff0c;左上角缩放&#xff0c;右上角缩放&#xff0c;左下角缩放&#xff0c;右下角缩放Bitmap中心缩放&#xff0c;包含了缩放和平移两个操作&#xf…