一文读懂Vue生命周期(Vue2)

news2024/9/21 18:56:15

一文读懂Vue生命周期(Vue2)

目录

    • 一文读懂Vue生命周期(Vue2)
      • 1 前言
      • 2 Vue生命周期
        • 2.1 基本生命周期
          • 2.1.1 8个生命周期
          • 2.1.2 案例
        • 2.2 组件生命周期
          • 2.2.1 父子生命周期
          • 2.2.2 案例
        • 2.3 keep-alive生命周期
          • 2.3.1 案例
        • 2.4 其他
      • 3 总结

vue生命周期详解,vue更新生命周期,keepalive生命周期,

1 前言

对于一个Vue开发者而言,学习Vue生命周期是必不可少的内容,事实上学习Vue生命周期对于开发高质量的Vue应用至关重要。在初级阶段,需要学习基本组件的生命周期,以了解页面的加载逻辑。而在Vue工程化阶段,就必须要对Vue生命周期有更深的了解。这对以下几个方面来说是基础:

  1. 理解组件行为:通过了解Vue的生命周期,你可以更深入地理解Vue组件是如何创建、更新和销毁的。这有助于你预测组件在不同阶段的行为,并避免潜在的问题。
  2. 优化性能:在生命周期的不同阶段,你可以执行特定的操作来优化应用的性能。例如,在created阶段,你可以进行数据的初始化或发送网络请求,以避免在模板渲染时产生不必要的延迟。在beforeDestroy阶段,你可以清除定时器、解绑全局事件或销毁子组件,以防止内存泄漏。
  3. 更好的状态管理:Vue的生命周期允许你在组件的不同状态下执行特定的逻辑。例如,在updated阶段,你可以检查数据的变化并据此更新DOM或触发其他操作。这有助于你更好地管理组件的状态和响应数据的变化。

2 Vue生命周期

学习Vue生命周期是从简单到复杂的循序渐进过程,以下我们把其拆解成三个部分:

  1. 基本生命周期:单个Vue实例的生命周期;
  2. 组件生命周期:添加子组件时加载的生命周期;
  3. keep-alive生命周期:当使用keep-alive包裹组件时,该组件的生命周期;
2.1 基本生命周期
2.1.1 8个生命周期

Vue2基本生命周期钩子函数有11个,主要的生命周期有8个;主要的8个生命周期如下:

  1. beforeCreate(创建前):在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用。
  2. created(创建后):在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算,以及 watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
  3. beforeMount(挂载前):在挂载开始之前被调用:相关的 render 函数首次被调用。此时模板编译已经完成但是还未挂载到页面上。
  4. mounted(挂载后):el 被新创建的 vm.el替换,并挂载到实例上去之后调用该钩子。如果root实例挂载了一个in−document元素,当mounted被调用时vm.el 也在文档内。此时可以访问到 $el 属性,也可以操作 DOM 和通过 AJAX 获取数据。
  5. beforeUpdate(更新前):数据更新时调用,发生在虚拟DOM打补丁之前。可以在这个钩子中访问现有的DOM,比如手动移除已添加的事件监听器。
  6. updated(更新后):由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件DOM已经更新,所以你现在可以执行依赖于DOM的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。
  7. beforeDestroy(销毁前):实例销毁之前调用。在这一步中,实例仍然完全可用。
  8. destroyed(销毁后):Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑,所有的事件监听器都会被移除,所有的子实例也会被销毁。

官网对8个生命周期图解如下:

生命周期

2.1.2 案例

仅仅学习理论是不够的,我们来通过案例来看各个生命周期实际执行顺序和各个生命周期能访问得到的内容:

执行顺序:

直接上最简单的能触发所有生命周期代码:

<template>
  <div>
    <title ref="myPage">生命周期</title>
    <div>参数:{{ parama }}</div>
    <el-button @click="updateParama">更新数据</el-button>
    <el-button @click="leavePage">离开页面</el-button>
  </div>
</template>
<script>
import Vue from "vue";
import { Button } from "element-ui";
Vue.use(Button);

export default {
  beforeCreate() {
    console.log("页面加载:beforeCreate");
  },
  created() {
    console.log("页面加载:created");
  },
  beforeMount() {
    console.log("页面加载:beforeMount");
  },
  mounted() {
    console.log("页面加载:mounted");
  },
  beforeUpdate() {
    console.log("页面更新:beforeUpdate");
  },
  updated() {
    console.log("页面更新:updated");
  },
  beforeDestroy() {
    console.log("页面销毁:beforeDestroy");
  },
  destroyed() {
    console.log("页面销毁:destroyed");
  },
  data() {
    return {
      parama: 0
    };
  },
  methods: {
    leavePage() {
      this.$router.push({ path: "/home" });
    },
    updateParama() {
      this.parama++;
    }
  }
};
</script>

页面效果如下:

在这里插入图片描述

当进入该页面时,触发前四个生命周期,执行顺序如控制台打印:

页面加载:beforeCreate
页面加载:created
页面加载:beforeMount
页面加载:mounted

当点击"更新数据"按钮时,依次触发beforeUpdate,updated;控制台打印:

页面更新:beforeUpdate
页面更新:updated

当点击“离开页面”按钮时,依次触发beforeDestroy,destroyed;控制台打印:

页面销毁:beforeDestroy
页面销毁:destroyed

大家可以复制代码自己试一下;

访问数据

再来看各个生命周期页面数据的访问情况,我们在每个生命周期都打印一下数据,代码如下:

beforeCreate() {
    console.log("页面加载:beforeCreate");
    console.log(this.parama);
  },
  created() {
    console.log("页面加载:created");
    console.log(this.parama);
  },
  beforeMount() {
    console.log("页面加载:beforeMount");
    console.log(this.parama);
  },
  mounted() {
    console.log("页面加载:mounted");
    console.log(this.parama);
  },
  beforeUpdate() {
    console.log("页面更新:beforeUpdate");
    console.log(this.parama);
  },
  updated() {
    console.log("页面更新:updated");
    console.log(this.parama);
  },
  beforeDestroy() {
    console.log("页面销毁:beforeDestroy");
    console.log(this.parama);
  },
  destroyed() {
    console.log("页面销毁:destroyed");
    console.log(this.parama);
  },

首先是页面加载时,控制台打印如下:

页面加载:beforeCreate
parama undefined

页面加载:created
parama 0

页面加载:beforeMount
parama 0

页面加载:mounted
parama 0

我们可以看到beforeCreate时是访问不到数据的,因为属性还未初始化;其他生命周期都能正常访问到数据。

我们再来看一下数据更新,点击“更新数据按钮”,控制台打印如下:

页面更新:beforeUpdate
parama 1

页面更新:updated
parama 1

我们可以看到两个更新的生命周期打印的数据相同,这里要注意的是,数据更新与生命周期触发的顺序是:

parama变成1 -> beforeUpdate -> updated

到这里大家都能明白生命周期顺序与数据访问之间的关系了。

2.2 组件生命周期
2.2.1 父子生命周期

当页面没有引入子组件时,如果没有做过异步处理,页面生命周期将会顺序执行,当引入子组件之后,父组件生命周期+子组件生命周期会交叉执行,具体执行顺序如下:

  • 页面加载:父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
  • 数据更新:当父子不涉及传参时,父子数据更新单独触发,不会相互影响;当父子涉及传参时:父beforeUpdate ->子beforeUpdate ->子updated->父updated
  • 组件销毁:父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
2.2.2 案例

我们看一下案例的完整代码,将上面的案例添加子组件代码,并将父组件的参数传给子组件,子组件参数传给父组件,页面如下:

在这里插入图片描述

父页面:

<template>
  <div>
    <title ref="myPage">生命周期</title>
    <div>父页面:</div>
    <div>参数:{{ parama }}</div>
    <div>子参数:{{ childData }}</div>
    <el-button @click="updateParama">更新父数据</el-button>
    <el-button @click="leavePage">离开页面</el-button>
    <child :param="parama" @childData="getChildData"></child>
  </div>
</template>
<script>
import Vue from "vue";
import { Button } from "element-ui";
import child from "./conponents/child";
Vue.use(Button);

export default {
  beforeCreate() {
    console.log("页面加载:beforeCreate");
    console.log("parama", this.parama);
  },
  created() {
    // await setTimeout({}, 1000);
    console.log("页面加载:created");
    console.log("parama", this.parama);
  },
  beforeMount() {
    console.log("页面加载:beforeMount");
    console.log("parama", this.parama);
  },
  mounted() {
    console.log("页面加载:mounted");
    console.log("parama", this.parama);
  },
  beforeUpdate() {
    console.log("页面更新:beforeUpdate");
    console.log("parama", this.parama);
  },
  updated() {
    console.log("页面更新:updated");
    console.log("parama", this.parama);
  },
  beforeDestroy() {
    console.log("页面销毁:beforeDestroy");
    console.log("parama", this.parama);
  },
  destroyed() {
    console.log("页面销毁:destroyed");
    console.log("parama", this.parama);
  },
  components: {
    child
  },
  data() {
    return {
      parama: 0,
      childData: 0
    };
  },
  methods: {
    leavePage() {
      this.$router.push({ path: "/home" });
    },
    updateParama() {
      this.parama++;
    },
    getChildData(a) {
      this.childData = a;
    }
  }
};
</script>

子组件:

<template>
  <div class="child">
    <title>子组件</title>
    <div>子组件:</div>
    <div>参数:{{ paramaChild }}</div>
    <div>父传参:{{ param }}</div>
    <el-button @click="updateParama">更新子页面数据</el-button>
  </div>
</template>
<script>
import Vue from "vue";
import { Button } from "element-ui";
Vue.use(Button);

export default {
  beforeCreate() {
    console.log("子页面加载:beforeCreate");
    console.log("paramaChild", this.paramaChild);
  },
  created() {
    // await setTimeout({}, 1000);
    console.log("子页面加载:created");
    console.log("paramaChild", this.paramaChild);
  },
  beforeMount() {
    console.log("子页面加载:beforeMount");
    console.log("paramaChild", this.paramaChild);
  },
  mounted() {
    console.log("子页面加载:mounted");
    console.log("paramaChild", this.paramaChild);
  },
  beforeUpdate() {
    console.log("子页面更新:beforeUpdate");
    console.log("paramaChild", this.paramaChild);
  },
  updated() {
    console.log("子页面更新:updated");
    console.log("paramaChild", this.paramaChild);
  },
  beforeDestroy() {
    console.log("子页面销毁:beforeDestroy");
    console.log("paramaChild", this.paramaChild);
  },
  destroyed() {
    console.log("子页面销毁:destroyed");
    console.log("paramaChild", this.paramaChild);
  },
  props: {
    param: Number
  },
  data() {
    return {
      paramaChild: 0
    };
  },
  methods: {
    updateParama() {
      this.paramaChild++;
      this.$emit("childData", this.paramaChild);
    }
  }
};
</script>
<style>
.child {
  margin: 20px;
  border: 1px solid gray;
}
</style>

  • 页面加载

页面加载时,父子生命周期:父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted

控制台日志如下:

页面加载:beforeCreate
parama undefined
页面加载:created
parama 0
页面加载:beforeMount
parama 0
子页面加载:beforeCreate
undefined
子页面加载:created
paramaChild 0
子页面加载:beforeMount
paramaChild 0
子页面加载:mounted
paramaChild 0
页面加载:mounted
parama 0
  • 页面更新

页面更新的情况分两类;

一类是父子组件不涉及传参,这种情况下,父页面参数更新不会触发子组件更新的生命周期,子组件的数据更新也不会触发父页面的生命周期。

第二类是父子组件涉及传参,不管是父传子还是子传父,父子生命周期相同,都为:父beforeUpdate ->子beforeUpdate ->子updated->父updated。

在以上父子相互传参案例下,我们点击父页面按钮:更新父数据;以及点击子组件按钮:更新子页面数据;控制台打印顺序都如下:

页面更新:beforeUpdate
子页面更新:beforeUpdate
子页面更新:updated
页面更新:updated
  • 页面销毁

页面销毁

点击”离开页面“按钮:控制台打印顺序如下:

页面销毁:beforeDestroy
子页面销毁:beforeDestroy
子页面销毁:destroyed
页面销毁:destroyed

2.3 keep-alive生命周期

<KeepAlive> 是一个内置组件,它的功能是在多个组件间动态切换时缓存被移除的组件实例。被缓存的实例普通Vue实例相比,多了activateddeactivated两个生命周期。

  • activated:被 keep-alive 缓存的组件激活时调用。
  • deactivated:被 keep-alive 缓存的组件失活时调用。

光这两个生命周期来讲,就是组件激活和失活的时候调用,但直到这个是不够的,这两个生命周期与其他八个生命周期顺序是什么样子的呢,我们先说结论:(子组件被keep-alive包裹)

  • 页面加载:父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->子activated(当子组件初次加载即可见时)->父mounted
  • 数据更新导致组件失活:父beforeUpdate ->子deactivated->父updated
  • 父页面销毁:父beforeDestroy->子deactivated(如果销毁前子组件是激活状态)->子beforeDestroy->子destroyed->父destroyed

我们结合案例来看实际情况;

2.3.1 案例

我们在案列中添加了一个组件来用于子组件的切换,并在子组件中添加activateddeactivated两个生命周期的监听函数,添加的代码如下:

父页面:

<template>
  <div>
    <title ref="myPage">生命周期</title>
    <div>父页面:</div>
    <div>参数:{{ parama }}</div>
    <div>子参数:{{ childData }}</div>
    <el-button @click="changeActiveCom">更换组件</el-button>
    <el-button @click="leavePage">离开页面</el-button>
    <keep-alive>
      <component :is="activeComponent"></component>
    </keep-alive>
  </div>
</template>
<script>
import Vue from "vue";
import { Button } from "element-ui";
import child from "./conponents/child";
import comA from "./conponents/comA";
Vue.use(Button);

export default {
  beforeCreate() {
    console.log("页面加载:beforeCreate");
    console.log("parama", this.parama);
  },
  created() {
    // await setTimeout({}, 1000);
    console.log("页面加载:created");
    console.log("parama", this.parama);
  },
  beforeMount() {
    console.log("页面加载:beforeMount");
    console.log("parama", this.parama);
  },
  mounted() {
    console.log("页面加载:mounted");
    console.log("parama", this.parama);
  },
  beforeUpdate() {
    console.log("页面更新:beforeUpdate");
    console.log("parama", this.parama);
  },
  updated() {
    console.log("页面更新:updated");
    console.log("parama", this.parama);
  },
  beforeDestroy() {
    console.log("页面销毁:beforeDestroy");
    console.log("parama", this.parama);
  },
  destroyed() {
    console.log("页面销毁:destroyed");
    console.log("parama", this.parama);
  },
  components: {
    child,
    comA
  },
  data() {
    return {
      parama: 0,
      childData: 0,
      activeComponent: "child"
    };
  },
  methods: {
    leavePage() {
      this.$router.push({ path: "/home" });
    },
    updateParama() {
      this.parama++;
    },
    getChildData(a) {
      this.childData = a;
    },
    changeActiveCom() {
      this.activeComponent = this.activeComponent == "comA" ? "child" : "comA";
    }
  }
};
</script>

    

子组件child:

  activated() {
    console.log("child组件激活:activated");
  },
  deactivated() {
    console.log("child组件失活:deactivated");
  },

页面效果:

在这里插入图片描述

点击**更换组件**按钮实现组件切换功能,用于触发activateddeactivated两个生命周期,

  • 页面加载

页面加载时打印结果如下:

页面加载:beforeCreate
页面加载:created
页面加载:beforeMount
子页面加载:beforeCreate
子页面加载:created
子页面加载:beforeMount
子页面加载:mounted
child组件激活:activated
页面加载:mounted

  • 页面更新

点击更换组件按钮其实就进行了data数据更新操作,如果组件进入不可见状态,此时控制台打印日志如下:

页面更新:beforeUpdate
child组件失活:deactivated
页面更新:updated

如果组件进入可见状态,控制台打印如下:

页面更新:beforeUpdate
child组件失活:activated
页面更新:updated
  • 页面销毁

点击离开页面按钮,父页面销毁,此时子组件页销毁,若是此时子组件处于激活状态,那么控制台打印如下:

页面销毁:beforeDestroy
child组件失活:deactivated
子页面销毁:beforeDestroy
子页面销毁:destroyed
页面销毁:destroyed

大家可以进行案例尝试;

2.4 其他

生命周期不是一成不变的,当生命周期执行异步操作时,生命周期的结束时间顺序就可能发生变化;如下我们在父组件created执行异步操作:

  async created() {
    await setTimeout({}, 1000);
    console.log("页面加载:created");
  },

此时控制台打印日志如下

页面加载:beforeCreate
页面加载:beforeMount
页面加载:mounted
页面加载:created

我们可以看到,created是最后执行完的;由此,要注意异步操作的生命周期变化。

若是我们在相应生命周期做了异步操作,并返回相应的值,在后续生命周期可能会出现无法渠道返回值的情况,这也是实际生产开发容易出问题的点。特别是生产情况客户手机网络较慢的情况下。

3 总结

掌握 Vue.js 的生命周期非常重要,因为它允许你在组件的不同阶段执行自定义的代码,从而实现对组件行为的精细控制和管理。但同时也有一些注意事项,以下也是一些注意事项:

  1. 避免在 render 函数中直接修改数据:render 函数中修改数据可能会导致不可预料的结果,因为 render 函数是用来生成虚拟 DOM 的,应该是一个纯函数。如果需要在渲染过程中修改数据,应该使用 computed 属性或者 watch 监听器。
  2. 谨慎使用异步操作: 在生命周期钩子函数中进行异步操作时,一定要注意异步操作完成的时机和影响。尤其是在 created 钩子中,当组件实例已经创建但是 DOM 还未挂载时,执行异步操作可能会导致一些问题。最好的做法是在 mounted 钩子中执行异步操作。
  3. 避免频繁使用 beforeUpdateupdated 虽然 beforeUpdateupdated 钩子提供了在组件更新时执行逻辑的机会,但频繁使用这些钩子可能会导致性能问题。应该仔细考虑哪些逻辑需要在组件更新时执行,以避免不必要的性能开销。
  4. 合理利用 activateddeactivated 钩子: 当使用 <keep-alive> 组件缓存组件时,activateddeactivated 钩子会被调用。在这些钩子中,你可以执行一些与组件缓存和恢复相关的逻辑,比如重置组件状态或重新加载数据。
  5. beforeDestroy 进行清理:beforeDestroy 钩子中,你可以执行一些清理工作,比如清除定时器、取消订阅、解绑事件等。这样可以确保在组件销毁前进行必要的资源释放,避免内存泄漏和其他问题。

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

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

相关文章

【Linux 基础 IO】文件系统

文章目录 1.初步理解文件2. fopen ( )的详解 1.初步理解文件 &#x1f427;① 打开文件&#xff1a; 本质是进程打开文件&#xff1b; &#x1f427;②文件没有被打开的时候在哪里呢&#xff1f; ----- 在磁盘中&#xff1b; &#x1f427;③进程可以打开很多个文件吗&#xff…

鸿蒙内核源码分析(消息队列篇) | 进程间如何异步传递大数据

基本概念 队列又称消息队列&#xff0c;是一种常用于任务间通信的数据结构。队列接收来自任务或中断的不固定长度消息&#xff0c;并根据不同的接口确定传递的消息是否存放在队列空间中。 任务能够从队列里面读取消息&#xff0c;当队列中的消息为空时&#xff0c;挂起读取任务…

408数据结构-树与森林 自学知识点整理

前置知识&#xff1a;树的基本概念与性质 树的存储结构 树既可以采用顺序存储结构&#xff0c;又可采用链式存储结构。但无论采取哪种方式&#xff0c;都要求能够唯一地反映树中各结点之间的逻辑关系。 1. 双亲表示法 这种存储结构采用一组连续空间来存储每个结点&#xff0…

模拟电路设计与分析——电流

&#x1f3ac; 秋野酱&#xff1a;《个人主页》 &#x1f525; 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 原子电流的产生电流的单位电流的方向直流电交流电直流&交流对比开路&闭路 原子 世界万物都是由原子构成&#xff0c;那么…

Pytorch实现图片异常检测

图片异常检测 异常检测指的是在正常的图片中找到异常的数据&#xff0c;由于无法通过规则进行识别判断&#xff0c;这样的应用场景通常都是需要人工进行识别&#xff0c;比如残次品的识别&#xff0c;图片异常识别模型的目标是可以代替或者辅助人工进行识别异常图片。 AnoGAN…

P8800 [蓝桥杯 2022 国 B] 卡牌

P8800 [蓝桥杯 2022 国 B] 卡牌 分析 “最多” -- 二分 1.二分区间&#xff08;凑齐的卡牌套数&#xff09;&#xff1a; l&#xff1a;a[]min&#xff1b;r&#xff1a;(a[]b[])max 2.check(x)&#xff1a; &#xff08;1&#xff09;for循环内&#xff1a; 判断x - a[i…

ComfyUI 基础教程(十三):ComfyUI-Impact-Pack 面部修复

SD的WebUI 中的面部修复神器 ADetailer,无法在ComfyUI 中使用。那么如何在ComfyUI中进行面部处理呢?ComfyUI 中也有几个面部修复功能,比如ComfyUI Impact Pack(FaceDetailer),以及换脸插件Reactor和IPAdapter。 ComfyUI-Impact-Pack 是一个功能强大的插件,专为 ComfyUI …

矩池云jupyter运行opengait代码 未完成版

文章目录 前言——矩池云的使用技巧1.切换源 一、下载数据集二、下载模型三、环境配置1.查看python、torch、torchvision版本2.查看一些包版本是否过高3.下载包 四、开始训练1.设置环境变量2.遇到的问题&#xff08;1&#xff09;torch.cuda.is_available()返回false&#xff0…

《第一行代码》第二版学习笔记(8)——网络技术

文章目录 一、Http1、HttpURLConnection2、OKHttp 二、解析JSON格式数据1、使用JSONObject2、使用GSON解析JSON数据 一、Http 1、HttpURLConnection public void run() {HttpURLConnection connection null;BufferedReader reader null;try {URL url new URL("http://…

springboot版本升级,及解决springsecurity漏洞问题

背景&#xff1a; 项目中要解决 Spring Security RegexRequestMatcher 认证绕过漏洞&#xff08;CVE-2022-22978&#xff09; 漏洞问题&#xff0c;并且需要将项目的版本整体升级到boot版本2.1.7&#xff0c;升级改造过程非常的痛苦&#xff0c;一方面对整个框架的代码不是很熟…

嵌入式复习重点

嵌入式系统有多种表现形式&#xff0c;包括计算机MCU、SOC片上系统、SOPC片上系统、GPU和FPGA等。 MCU(微控制器): 是最基本也是最常见的嵌入式系统形式,是集成了CPU、ROM、RAM、IO口、定时器、中断控制器等组件的单一芯片。MCU广泛用于电器电子产品的控制。SoC(系统片上芯片):…

vivado UltraScale 比特流设置

下表所示 UltraScale ™ 器件的器件配置设置可搭配 set_property <Setting> <Value> [current_design] Vivado 工具 Tcl 命令一起使用。

地下管线管网三维参数化建模软件MagicPipe3D V3.5

经纬管网建模系统MagicPipe3D&#xff08;www.magic3d.net&#xff09;自主安全可控&#xff0c;本地离线参数化构建三维管网模型&#xff08;管道、接头、附属物等&#xff09;&#xff0c;输出标准3DTiles、Obj等格式&#xff0c;支持Cesium、Unreal、Unity等引擎可视化查询分…

09_电子设计教程基础篇(电阻)

文章目录 前言一、电阻原理二、电阻种类1.固定电阻1、材料工艺1、线绕电阻2、非线绕电阻1、实心电阻1、有机实心电阻2、无机实心电阻 2、薄膜电阻&#xff08;常用&#xff09;1、碳膜电阻2、合成碳膜电阻3、金属膜电阻4、金属氧化膜电阻5、玻璃釉膜电阻 3、厚膜电阻&#xff0…

Jenkins 2.164.3 安装插件(当前官网正式版本: 2.440.3 LTS)

Jenkins 2.164.3安装插件 1. 安装jenkins1.1 宿主机安装1.2 docker安装(linux) 2. 登录jenkins3. 修改配置文件 这篇文章如果放在5、6年前写出来毫无意义&#xff0c;因为安装2.164.3之后&#xff0c;推荐的插件即可自动安装。但是在2024年&#xff0c;当前正式版本是2.440.3 L…

武汉星起航:跨境电商行业领航者,一站式孵化服务引领全球趋势

在全球化日益深入的今天&#xff0c;跨境电商作为连接各国市场的桥梁&#xff0c;其重要性日益凸显。在这一潮流中&#xff0c;武汉星起航电子商务有限公司以其前瞻性的战略眼光和丰富的运营经验&#xff0c;迅速崛起为跨境电商行业的领军者。公司不仅自营亚马逊跨境电商业务&a…

echarts柱状图实现左右横向对比

实现效果如上图 其实是两组数据&#xff0c;其中一组数据改为负数&#xff0c;然后 在展示的时候&#xff0c;在将负数取反 第一处修改坐标轴 xAxis: [{type: value,axisLabel: {formatter: function (value) {if (value < 0) {return -value;}else{return value;}}}}], 第…

书客大路灯Sun自掀起护眼新浪潮以来,纷纷直呼“真香现场”

随着科技时代与人们生活水平需求的日益增长&#xff0c;加上网课学习和居家办公的普及&#xff0c;各大灯具厂商都开始搭建起自家的生态&#xff0c;尤其是大路灯这个以外不被重视的品类&#xff0c;也开始找到了自身的定位与价值。 尤其在2024年上半年发布的——SUKER书客护眼…

截取字符串的3种方法

一、截取字符串的实现 在C语言中&#xff0c;没有直接截取字符串的库函数&#xff0c;但是咱们可以借助其他函数实现这个功能。 1&#xff0e;最简单的方法 如果只是直接输出一个字符串的子串&#xff0c;只需要一个简单的printf函数即可。 #include <stdio.h> int m…

MySQL之查询 拿下 * 。*

DQL数据查询语言 对上述的的查询操作进行代码演示&#xff08;续上一篇学生表代码进行处理&#xff09; 下面是上一篇的代码分享 下面进行简单的查询操作 字符串如果强行进行算数运算默认只为0 查询时常用的单行函数列举 未完待续