大白话 Vue 中的keep - alive组件,它的作用是什么?在什么场景下使用?

news2025/3/13 17:28:55

大白话 Vue 中的keep - alive组件,它的作用是什么?在什么场景下使用?

什么是 keep-alive 组件

在 Vue 里,keep-alive 是一个内置组件,它就像是一个“保存盒”,能把组件实例保存起来,而不是每次切换组件时都销毁再重新创建。这就好比你有一堆玩具,每次不玩某个玩具时,不把它扔掉,而是放到一个盒子里存着,下次再玩的时候直接从盒子里拿出来接着玩,这样就节省了重新制造玩具的时间和精力。

keep-alive 的作用

  1. 减少组件创建和销毁的开销:组件的创建和销毁是需要消耗性能的,尤其是那些初始化过程比较复杂的组件。使用 keep-alive 可以避免重复创建和销毁这些组件,从而提升应用的性能。
  2. 保留组件的状态:当组件被 keep-alive 包裹后,它的状态会被保留下来。比如一个表单组件,用户在里面填了一些信息,切换到其他组件再切回来时,表单里的信息还在,不用重新填写。

适用场景

  1. 多标签页切换:在一个应用里有多个标签页,每个标签页对应一个组件,用户在不同标签页之间切换时,使用 keep-alive 可以保留每个标签页组件的状态。
  2. 列表页和详情页的切换:从列表页进入详情页,再返回列表页时,列表页的滚动位置、筛选条件等状态可以通过 keep-alive 保留下来。

代码示例及解释

基础使用
<template>
  <!-- 这里使用 keep-alive 组件包裹了两个子组件 -->
  <keep-alive>
    <!-- 动态组件,根据 currentComponent 变量的值来决定显示哪个组件 -->
    <component :is="currentComponent"></component>
  </keep-alive>
  <!-- 按钮,点击切换显示的组件 -->
  <button @click="toggleComponent">切换组件</button>
</template>

<script>
import ComponentA from './ComponentA.vue';
import ComponentB from './ComponentB.vue';

export default {
  data() {
    return {
      // 初始显示的组件是 ComponentA
      currentComponent: 'ComponentA'
    };
  },
  components: {
    // 注册组件
    ComponentA,
    ComponentB
  },
  methods: {
    toggleComponent() {
      // 点击按钮时切换显示的组件
      this.currentComponent = this.currentComponent === 'ComponentA' ? 'ComponentB' : 'ComponentA';
    }
  }
};
</script>
代码解释
  • <keep-alive> 标签:把需要保存状态的组件包裹起来,这样在切换组件时,被包裹的组件不会被销毁,而是被缓存起来。
  • <component :is="currentComponent"></component>:这是 Vue 的动态组件,currentComponent 是一个变量,它的值决定了显示哪个组件。
  • toggleComponent 方法:点击按钮时,会改变 currentComponent 的值,从而切换显示的组件。
配合 includeexclude 使用
<template>
  <!-- 使用 include 属性指定只缓存 ComponentA 组件 -->
  <keep-alive include="ComponentA">
    <component :is="currentComponent"></component>
  </keep-alive>
  <button @click="toggleComponent">切换组件</button>
</template>

<script>
import ComponentA from './ComponentA.vue';
import ComponentB from './ComponentB.vue';

export default {
  data() {
    return {
      currentComponent: 'ComponentA'
    };
  },
  components: {
    ComponentA,
    ComponentB
  },
  methods: {
    toggleComponent() {
      this.currentComponent = this.currentComponent === 'ComponentA' ? 'ComponentB' : 'ComponentA';
    }
  }
};
</script>
代码解释
  • include 属性include 属性可以指定只缓存哪些组件,只有组件名匹配 include 属性值的组件才会被缓存。这里只缓存 ComponentA 组件。
  • exclude 属性:和 include 相反,exclude 属性指定哪些组件不被缓存。
组件内的生命周期钩子
<script>
export default {
  data() {
    return {
      count: 0
    };
  },
  // 组件被激活时触发
  activated() {
    console.log('组件被激活');
  },
  // 组件被停用时触发
  deactivated() {
    console.log('组件被停用');
  }
};
</script>
代码解释
  • activated 钩子:当被 keep-alive 缓存的组件被激活时,会触发 activated 钩子,可以在这个钩子函数里做一些初始化操作,比如重新获取数据。
  • deactivated 钩子:当被 keep-alive 缓存的组件被停用时,会触发 deactivated 钩子,可以在这个钩子函数里做一些清理操作。

总之,keep-alive 组件在提升 Vue 应用性能和保留组件状态方面非常有用,合理使用它可以让你的应用更加流畅和易用。

如何在Vue中使用keep-alive组件?

在Vue里,keep-alive组件的作用是把组件实例缓存起来,这样在切换组件时,就不用反复销毁和重新创建组件实例,能够提升性能和用户体验。接下来我会详细介绍怎样在Vue里使用keep-alive组件,并且在每句代码上添加注释。

1. 创建一个简单的Vue项目

要是你还没有Vue项目,就可以借助Vue CLI来创建一个新的项目:

npm install -g @vue/cli
vue create my-keep-alive-project
cd my-keep-alive-project

2. 创建两个组件

src/components目录下创建两个组件,分别是ComponentA.vueComponentB.vue

ComponentA.vue
<template>
  <!-- 组件A的模板部分 -->
  <div>
    <h1>这是组件A</h1>
    <!-- 显示计数器的值 -->
    <p>计数器: {{ count }}</p>
    <!-- 点击按钮增加计数器的值 -->
    <button @click="increment">增加</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      // 初始化计数器为0
      count: 0
    };
  },
  methods: {
    increment() {
      // 点击按钮时计数器加1
      this.count++;
    }
  },
  // 组件被激活时触发
  activated() {
    console.log('组件A被激活');
  },
  // 组件被停用(缓存)时触发
  deactivated() {
    console.log('组件A被停用');
  }
};
</script>
ComponentB.vue
<template>
  <!-- 组件B的模板部分 -->
  <div>
    <h1>这是组件B</h1>
    <!-- 显示计数器的值 -->
    <p>计数器: {{ count }}</p>
    <!-- 点击按钮增加计数器的值 -->
    <button @click="increment">增加</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      // 初始化计数器为0
      count: 0
    };
  },
  methods: {
    increment() {
      // 点击按钮时计数器加1
      this.count++;
    }
  },
  // 组件被激活时触发
  activated() {
    console.log('组件B被激活');
  },
  // 组件被停用(缓存)时触发
  deactivated() {
    console.log('组件B被停用');
  }
};
</script>

3. 在App.vue中使用keep-alive组件

<template>
  <div id="app">
    <!-- 导航按钮,点击切换组件 -->
    <button @click="currentComponent = 'ComponentA'">切换到组件A</button>
    <button @click="currentComponent = 'ComponentB'">切换到组件B</button>
    <!-- 使用keep-alive组件来缓存组件实例 -->
    <keep-alive>
      <!-- 根据currentComponent的值动态渲染组件 -->
      <component :is="currentComponent"></component>
    </keep-alive>
  </div>
</template>

<script>
// 引入组件A和组件B
import ComponentA from './components/ComponentA.vue';
import ComponentB from './components/ComponentB.vue';

export default {
  components: {
    // 注册组件A和组件B
    ComponentA,
    ComponentB
  },
  data() {
    return {
      // 初始显示组件A
      currentComponent: 'ComponentA'
    };
  }
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

代码解释

  1. 组件创建ComponentA.vueComponentB.vue这两个组件里都有一个计数器,并且有一个“增加”按钮,点击按钮就能让计数器的值增加。
  2. keep-alive组件使用:在App.vue里,借助<keep-alive>标签把<component>包裹起来,这样就能缓存组件实例。当在组件A和组件B之间进行切换时,组件实例不会被销毁,而是被缓存起来。
  3. activateddeactivated钩子:在ComponentA.vueComponentB.vue里,运用了activateddeactivated钩子函数。activated在组件被激活(显示)时触发,deactivated在组件被停用(隐藏)时触发。

运行项目

在终端中执行以下命令来运行项目:

npm run serve

之后在浏览器里访问http://localhost:8080,你就能看到两个按钮,点击按钮就能在组件A和组件B之间进行切换。当你切换组件时,计数器的值会被保留,这就表明组件实例被缓存了。

除了上述场景,还有哪些场景适合使用keep-alive组件?

keep - alive组件是Vue.js中的一个内置组件,它的主要作用是在组件切换时,保留组件的状态,避免重新渲染,从而提高性能和用户体验。以下是一些除了常见场景外,还适合使用keep - alive组件的场景及示例代码:

电商平台的商品详情页

  • 场景描述:当用户在电商平台中查看商品详情时,可能会频繁地在不同商品之间切换。如果不使用keep - alive组件,每次切换商品详情页都需要重新获取商品数据、渲染页面,这会导致一定的延迟,影响用户体验。使用keep - alive组件可以在用户切换商品时,保留之前商品详情页的状态,下次再回到该商品详情页时,无需重新加载数据和渲染,直接显示之前的状态,提高了页面的加载速度和响应性能。
  • 代码示例
<template>
  <div>
    <!-- 使用keep - alive组件包裹商品详情组件 -->
    <keep - alive>
      <!-- 商品详情组件,:key属性用于区分不同的商品,确保每个商品都有独立的缓存 -->
      <product - detail :key="productId" :product="product"></product - detail>
    </keep - alive>
  </div>
</template>

<script>
import ProductDetail from '@/components/ProductDetail.vue'

export default {
  components: {
    ProductDetail
  },
  data() {
    return {
      // 商品ID
      productId: '',
      // 商品数据
      product: {}
    }
  },
  methods: {
    // 加载商品详情数据的方法
    loadProductDetail(productId) {
      // 这里可以通过API请求获取商品详情数据
      // 假设返回的商品数据格式为{id, name, description, etc.}
      this.productId = productId
      this.product = {
        id: productId,
        name: 'Product Name',
        description: 'Product Description'
        // 其他商品属性
      }
    }
  }
}
</script>

多标签页的后台管理系统

  • 场景描述:在后台管理系统中,用户通常会打开多个标签页来进行不同的操作,如查看订单、管理用户、编辑文章等。当用户在不同标签页之间切换时,使用keep - alive组件可以保留每个标签页的组件状态,避免重复加载和渲染。这样,用户再次回到某个标签页时,能够快速恢复到之前的操作状态,提高工作效率。
  • 代码示例
<template>
  <div>
    <!-- 导航栏,用于切换不同的标签页 -->
    <ul>
      <li v - for="(tab, index) in tabs" :key="index" @click="activeTab = index">
        {{ tab.title }}
      </li>
    </ul>
    <!-- 使用keep - alive组件包裹标签页内容 -->
    <keep - alive>
      <!-- 根据当前激活的标签页索引,渲染对应的组件 -->
      <component :is="activeTabComponent"></component>
    </keep - alive>
  </div>
</template>

<script>
import OrderList from '@/components/OrderList.vue'
import UserManagement from '@/components/UserManagement.vue'
import ArticleEditor from '@/components/ArticleEditor.vue'

export default {
  components: {
    OrderList,
    UserManagement,
    ArticleEditor
  },
  data() {
    return {
      // 标签页列表,包含每个标签页的标题和对应的组件名称
      tabs: [
        { title: '订单列表', component: 'OrderList' },
        { title: '用户管理', component: 'UserManagement' },
        { title: '文章编辑', component: 'ArticleEditor' }
      ],
      // 当前激活的标签页索引
      activeTab: 0
    }
  },
  computed: {
    // 根据当前激活的标签页索引,计算出要渲染的组件
    activeTabComponent() {
      return this.tabs[this.activeTab].component
    }
  }
}
</script>

向导式表单

  • 场景描述:在一些需要用户填写大量信息的向导式表单中,用户可能会在不同步骤之间来回切换。使用keep - alive组件可以保留每个步骤表单的输入状态,避免用户在返回上一步时丢失已输入的数据,提高用户填写表单的体验和效率。
  • 代码示例
<template>
  <div>
    <!-- 向导式表单导航栏,显示当前步骤和总步骤数 -->
    <div>
      步骤 {{ currentStep + 1 }} / {{ steps.length }}
    </div>
    <!-- 步骤切换按钮 -->
    <button v - if="currentStep > 0" @click="prevStep">上一步</button>
    <button v - if="currentStep < steps.length - 1" @click="nextStep">下一步</button>
    <!-- 使用keep - alive组件包裹表单步骤组件 -->
    <keep - alive>
      <!-- 根据当前步骤索引,渲染对应的表单步骤组件 -->
      <component :is="currentStepComponent"></component>
    </keep - alive>
  </div>
</template>

<script>
import Step1Form from '@/components/Step1Form.vue'
import Step2Form from '@/components/Step2Form.vue'
import Step3Form from '@/components/Step3Form.vue'

export default {
  components: {
    Step1Form,
    Step2Form,
    Step3Form
  },
  data() {
    return {
      // 表单步骤列表,包含每个步骤对应的组件名称
      steps: [
        'Step1Form',
        'Step2Form',
        'Step3Form'
      ],
      // 当前步骤索引
      currentStep: 0
    }
  },
  computed: {
    // 根据当前步骤索引,计算出要渲染的组件
    currentStepComponent() {
      return this.steps[this.currentStep]
    }
  },
  methods: {
    // 上一步方法,切换到上一个步骤
    prevStep() {
      if (this.currentStep > 0) {
        this.currentStep--
      }
    },
    // 下一步方法,切换到下一个步骤
    nextStep() {
      if (this.currentStep < this.steps.length - 1) {
        this.currentStep++
      }
    }
  }
}
</script>

带有历史记录的搜索页面

  • 场景描述:在搜索页面中,用户可能会进行多次搜索,并希望能够快速回到之前的搜索结果页面。使用keep - alive组件可以缓存搜索结果页面的状态,包括搜索条件、排序方式、当前页码等,当用户从历史记录中点击返回时,能够直接恢复到之前的搜索结果页面,而无需重新执行搜索操作,提高了搜索效率和用户体验。
  • 代码示例
<template>
  <div>
    <!-- 搜索框,用于输入搜索关键词 -->
    <input type="text" v - model="searchKeyword" placeholder="请输入搜索关键词">
    <!-- 搜索按钮,点击触发搜索方法 -->
    <button @click="search">搜索</button>
    <!-- 历史记录列表,显示之前的搜索关键词 -->
    <ul>
      <li v - for="(keyword, index) in searchHistory" :key="index" @click="goBackToHistory(index)">
        {{ keyword }}
      </li>
    </ul>
    <!-- 使用keep - alive组件包裹搜索结果组件 -->
    <keep - alive>
      <!-- 搜索结果组件,传递搜索关键词和其他相关参数 -->
      <search - result :keyword="searchKeyword" :otherParams="otherParams"></search - result>
    </keep - alive>
  </div>
</template>

<script>
import SearchResult from '@/components/SearchResult.vue'

export default {
  components: {
    SearchResult
  },
  data() {
    return {
      // 搜索关键词
      searchKeyword: '',
      // 其他搜索参数,如排序方式、页码等
      otherParams: {
        sortBy: 'relevance',
        page: 1
      },
      // 搜索历史记录数组
      searchHistory: []
    }
  },
  methods: {
    // 搜索方法,执行搜索操作并将关键词添加到历史记录中
    search() {
      // 这里可以通过API请求进行搜索
      // 假设搜索结果为一个数组
      const searchResults = []
      // 将搜索关键词添加到历史记录中
      this.searchHistory.push(this.searchKeyword)
    },
    // 回到历史记录中的某个搜索结果页面的方法
    goBackToHistory(index) {
      // 将当前搜索关键词设置为历史记录中的关键词
      this.searchKeyword = this.searchHistory[index]
      // 可以根据需要设置其他参数,如恢复当时的排序方式和页码等
      this.otherParams.sortBy = 'relevance'
      this.otherParams.page = 1
    }
  }
}
</script>

在上述代码示例中,通过keep - alive组件包裹相应的组件,实现了在不同场景下保留组件状态的功能。这样可以避免组件的重复渲染和数据的重复加载,提高了应用程序的性能和用户体验。同时,通过合理地使用key属性和组件的切换逻辑,确保了每个组件都能正确地缓存和恢复状态。

在使用keep-alive时,可能会遇到哪些问题?

1. keep-alive 基本概念

keep-alive 是一种机制,在网络通信里,它能让客户端和服务器之间的连接在一次请求响应完成后不马上关闭,而是保持一段时间,这样后续的请求就能复用这个连接,减少建立新连接的开销。在前端开发里,Vue 框架中的 keep-alive 组件可用于缓存组件实例,避免重复创建和销毁组件,提升性能。

2. 使用 keep-alive 可能遇到的问题及解决办法

问题 1:缓存组件数据不更新
  • 问题描述:当使用 keep-alive 缓存组件后,组件里的数据不会随着路由切换或者外部数据变化而更新。
  • 解决办法:利用 activateddeactivated 生命周期钩子函数。activated 会在组件被激活时触发,deactivated 会在组件失活时触发。

以下是示例代码:

<template>
  <div>
    <!-- 使用 keep-alive 包裹路由视图 -->
    <keep-alive>
      <router-view></router-view>
    </keep-alive>
  </div>
</template>

<script>
export default {
  name: 'App',
};
</script>
<template>
  <div>
    <!-- 组件内容 -->
    <p>{{ message }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: '初始消息',
    };
  },
  // 组件被激活时触发
  activated() {
    // 在这里更新数据
    this.message = '更新后的消息';
  },
  // 组件失活时触发
  deactivated() {
    console.log('组件失活');
  },
};
</script>
问题 2:缓存组件太多,占用大量内存
  • 问题描述:要是缓存的组件过多,就会占用大量内存,影响应用性能。
  • 解决办法:使用 includeexclude 属性来控制哪些组件需要被缓存,或者使用 max 属性限制缓存组件的最大数量。

示例代码如下:

<template>
  <div>
    <!-- 使用 include 属性指定需要缓存的组件 -->
    <keep-alive include="ComponentA,ComponentB">
      <router-view></router-view>
    </keep-alive>
    <!-- 或者使用 max 属性限制缓存组件的最大数量 -->
    <keep-alive max="3">
      <router-view></router-view>
    </keep-alive>
  </div>
</template>

<script>
export default {
  name: 'App',
};
</script>
问题 3:缓存组件的滚动位置丢失
  • 问题描述:当切换路由时,缓存组件的滚动位置会丢失,每次返回组件时都会回到顶部。
  • 解决办法:在 activated 生命周期钩子函数里恢复滚动位置,在 deactivated 生命周期钩子函数里保存滚动位置。

示例代码:

<template>
  <div ref="scrollContainer" style="height: 200px; overflow-y: auto;">
    <!-- 模拟长列表 -->
    <p v-for="i in 100" :key="i">{{ i }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      scrollTop: 0, // 用于保存滚动位置
    };
  },
  // 组件被激活时触发
  activated() {
    // 恢复滚动位置
    this.$refs.scrollContainer.scrollTop = this.scrollTop;
  },
  // 组件失活时触发
  deactivated() {
    // 保存滚动位置
    this.scrollTop = this.$refs.scrollContainer.scrollTop;
  },
};
</script>

通过上述这些解决办法,你就能在使用 keep-alive 时避免常见问题,提升应用的性能和用户体验。

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

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

相关文章

使用Nodejs基于DeepSeek加chromadb实现RAG检索增强生成 本地知识库

定义 检索增强生成&#xff08;RAG&#xff09;的基本定义 检索增强生成&#xff08;Retrieval-Augmented Generation&#xff0c;简称RAG&#xff09;是一种结合了信息检索技术与语言生成模型的人工智能技术。RAG通过从外部知识库中检索相关信息&#xff0c;并将其作为提示&…

笔试刷题专题(一)

文章目录 最小花费爬楼梯&#xff08;动态规划&#xff09;题解代码 数组中两个字符串的最小距离&#xff08;贪心&#xff08;dp&#xff09;&#xff09;题解代码 点击消除题解代码 最小花费爬楼梯&#xff08;动态规划&#xff09; 题目链接 题解 1. 状态表示&#xff1…

LeetCode977有序数组的平方

思路①&#xff1a;先平方&#xff0c;后快排&#xff0c;输出&#xff08;基准元素&#xff0c;左小右大&#xff09; 时间复杂度&#xff1a;O&#xff08;nlogn&#xff09; 思路②&#xff1a;双指针左右开弓&#xff0c;首先原数组已经是按照非递减顺序排序&#xff0c;那…

网络变压器的主要电性参数与测试方法(4)

Hqst盈盛&#xff08;华强盛&#xff09;电子导读&#xff1a;网络变压器的主要电性参数与测试方法&#xff08;4&#xff09;.. 今天我们继续来看看网络变压器的2个重要电性参数与它的测试方法&#xff1a; 1.反射损耗&#xff08;Return loss&…

Windows10 WSL又又又一次崩了 Docker Desktop - Unexpected WSL error

问题&#xff1a;Windows10 WSL又又又一次崩了 这回报错&#xff1a; 然后再打开WSL Ubuntu就卡住了&#xff0c;等很长时间没反应&#xff0c;就关掉了。 手动启动Docker Desktop&#xff0c;报错&#xff1a; An unexpected error occurred while executing a WSL comman…

【前端基础】:HTML

超链接标签: a href: 必须具备, 表示点击后会跳转到哪个页面. target: 打开方式. 默认是 _self. 如果是 _blank 则用新的标签页打开 <a href"http://www.baidu.com">百度</a>链接的几种形式: 外部链接: href 引用其他网站的地址 <a href"http…

JVM垃圾收集器合集

前言&#xff1a;JVM GC收集器的回顾与比较 JVM&#xff08;Java虚拟机&#xff09;中的垃圾收集器是自动管理内存的重要机制&#xff0c;旨在回收不再使用的对象所占用的内存空间。以下是JVM中几种常见的垃圾收集器的详细介绍&#xff1a; 一、新生代垃圾收集器 1.Serial收集…

Sourcetree——使用.gitignore忽略文件或者文件夹

一、为何需要文件忽略机制&#xff1f; 1.1 为什么要会略&#xff1f; 对于开发者而言&#xff0c;明智地选择忽略某些文件类型&#xff0c;能带来三大核心优势&#xff1a; 仓库纯净性&#xff1a;避免二进制文件、编译产物等污染代码库 安全防护&#xff1a;防止敏感信息&…

本地部署 OpenManus 保姆级教程(Windows 版)

一、环境搭建 我的电脑是Windows 10版本&#xff0c;其他的没尝试&#xff0c;如果大家系统和我的不一致&#xff0c;请自行判断&#xff0c;基本上没什么大的出入啊。 openManus的Git地址&#xff1a;https://github.com/mannaandpoem/OpenManus 根据官网的两种安装推荐方式如…

视频推拉流:EasyDSS平台直播通道重连转推失败原因排查与解决

视频推拉流EasyDSS视频直播点播平台&#xff0c;集视频直播、点播、转码、管理、录像、检索、时移回看等功能于一体&#xff0c;可提供音视频采集、视频推拉流、播放H.265编码视频、存储、分发等视频能力服务。 用户使用EasyDSS平台对直播通道进行转推&#xff0c;发现只要关闭…

【科研绘图系列】python绘制分组点图(grouped dot plot)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包数据下载导入数据函数`generateRectBoxDF` 函数主要作用参数解释逻辑流程`nmfDotPlot` 函数主要作用参数解释逻辑流程画图1画图2画图3画图4介绍 【科研绘图系列】python绘制…

Springfox、Springdoc和Swagger

Springfox、Swagger 和 Springdoc Springfox、Swagger 和 Springdoc 是用于在 Spring Boot 项目中生成API文档的工具&#xff0c;但它们之间有显著的区别和演进关系&#xff1a; 1.Swagger 简介 Swagger 是一个开源项目&#xff0c;旨在为 RESTful APIs 提供交互式文档。最…

在Spring Boot项目中如何实现获取FTP远端目录结构

Java语言实现获取FTP远端目录结构的实现方式有多种,在Spring Boot 项目中,最简单和快速的方式就是使用Spring Integration 实现FTP相关的功能。 前言 本篇的示例和演示基于Windows 的FTP 服务,关于如何在Windows 开启FTP服务可以参考: Windows 如何开启和使用FTP服务 本…

Flutter_学习记录_device_info_plus 插件获取设备信息

引入三方库device_info_plus导入头文件 import package:device_info_plus/device_info_plus.dart;获取设备信息的主要代码 DeviceInfoPlugin deviceInfoPlugin DeviceInfoPlugin(); BaseDeviceInfo deviceInfo await deviceInfoPlugin.deviceInfo;完整案例 import package…

Java高频面试之集合-10

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本baby今天来报道了&#xff01;哈哈哈哈哈嗝&#x1f436; 面试官&#xff1a;详解红黑树&#xff1f;HashMap为什么不用二叉树/平衡树呢&#xff1f; 一、红黑树&#xff08;Red-Black Tree&#xff…

never_give_up

一个很有意思的题&#xff1a; never_give_up - Bugku CTF平台 注意到注释里面有1p.html&#xff0c;我们直接在源代码界面看&#xff0c;这样就不会跳转到它那个链接的&#xff1a; 然后解码可得&#xff1a; ";if(!$_GET[id]) {header(Location: hello.php?id1);exi…

Python Selenium库入门使用,图文详细。附网页爬虫、web自动化操作等实战操作。

文章目录 前言1 创建conda环境安装Selenium库2 浏览器驱动下载&#xff08;以Chrome和Edge为例&#xff09;3 基础使用&#xff08;以Chrome为例演示&#xff09;3.1 与浏览器相关的操作3.1.1 打开/关闭浏览器3.1.2 访问指定域名的网页3.1.3 控制浏览器的窗口大小3.1.4 前进/后…

AI4CODE】3 Trae 锤一个贪吃蛇的小游戏

【AI4CODE】目录 【AI4CODE】1 Trae CN 锥安装配置与迁移 【AI4CODE】2 Trae 锤一个 To-Do-List 这次还是采用 HTML/CSS/JAVASCRIPT 技术栈 Trae 锤一个贪吃蛇的小游戏。 1 环境准备 创建一个 Snake 的子文件夹&#xff0c;清除以前的会话记录。 2 开始构建 2.1 输入会…

Linux 进程的一生(一):进程与线程的创建机制解析

在 Linux 操作系统中&#xff0c;每个任务都以「进程」的形式存在。但 Linux 下的「线程」又是什么&#xff1f;Linux 并没有单独定义一种全新数据结构来表示线程&#xff0c;而是将线程视为一种特殊的进程——一种共享资源的轻量级进程。然而&#xff0c;在具体实现和运行机制…

STM32之I2C硬件外设

注意&#xff1a;硬件I2C的引脚是固定的 SDA和SCL都是复用到外部引脚。 SDA发送时数据寄存器的数据在数据移位寄存器空闲的状态下进入数据移位寄存器&#xff0c;此时会置状态寄存器的TXE为1&#xff0c;表示发送寄存器为空&#xff0c;然后往数据控制寄存器中一位一位的移送数…