鸿蒙OSUniApp 制作简洁高效的标签云组件#三方框架 #Uniapp

news2025/5/19 15:15:35

UniApp 制作简洁高效的标签云组件

在移动端应用中,标签云(Tag Cloud)是一种常见的UI组件,它以视觉化的方式展示关键词或分类,帮助用户快速浏览和选择感兴趣的内容。本文将详细讲解如何在UniApp框架中实现一个简洁高效的标签云组件,并探讨其实际应用场景。

前言

最近在做一个社区类App时,产品经理提出了一个需求:需要在首页展示热门话题标签,并且要求这些标签能够根据热度有不同的展示样式。起初我想到的是直接用现成的组件库,但翻遍了各大组件市场,却没找到一个既美观又符合我们需求的标签云组件。

无奈之下,只能自己动手来实现这个功能。经过几天的摸索和优化,终于做出了一个既简洁又实用的标签云组件。今天就把这个过程分享给大家,希望能对你有所帮助。

需求分析

在开始编码前,我们先来明确一下标签云组件应具备的核心功能:

  1. 灵活的布局:标签能够自动换行,适应不同尺寸的屏幕
  2. 可定制的样式:支持自定义颜色、大小、边框等样式
  3. 支持点击事件:点击标签能触发相应的操作
  4. 热度展示:能够根据标签的权重/热度展示不同的样式
  5. 性能优化:即使有大量标签,也不会影响应用性能

有了这些需求后,我们就可以开始设计并实现这个组件了。

基础组件实现

首先,我们创建一个标签云组件文件 tag-cloud.vue

<template>
  <view class="tag-cloud-container">
    <view 
      v-for="(item, index) in tags" 
      :key="index"
      class="tag-item"
      :class="[`tag-level-${item.level || 0}`, item.active ? 'active' : '']"
      :style="getTagStyle(item)"
      @tap="handleTagClick(item, index)"
    >
      <text>{{ item.name }}</text>
      <text v-if="showCount && item.count" class="tag-count">({{ item.count }})</text>
    </view>
  </view>
</template>

<script>
export default {
  name: 'TagCloud',
  props: {
    // 标签数据
    tags: {
      type: Array,
      default: () => []
    },
    // 是否显示标签数量
    showCount: {
      type: Boolean,
      default: false
    },
    // 自定义颜色配置
    colorMap: {
      type: Array,
      default: () => ['#8a9aa9', '#61bfad', '#f8b551', '#ef6b73', '#e25c3d']
    },
    // 最大字体大小 (rpx)
    maxFontSize: {
      type: Number,
      default: 32
    },
    // 最小字体大小 (rpx)
    minFontSize: {
      type: Number,
      default: 24
    }
  },
  methods: {
    // 处理标签点击事件
    handleTagClick(item, index) {
      this.$emit('click', { item, index });
    },
    
    // 获取标签样式
    getTagStyle(item) {
      const level = item.level || 0;
      const style = {};
      
      // 根据level确定字体大小
      if (this.maxFontSize !== this.minFontSize) {
        const fontStep = (this.maxFontSize - this.minFontSize) / 4;
        style.fontSize = `${this.minFontSize + level * fontStep}rpx`;
      }
      
      // 设置标签颜色
      if (this.colorMap.length > 0) {
        const colorIndex = Math.min(level, this.colorMap.length - 1);
        style.color = this.colorMap[colorIndex];
        style.borderColor = this.colorMap[colorIndex];
      }
      
      return style;
    }
  }
}
</script>

<style lang="scss">
.tag-cloud-container {
  display: flex;
  flex-wrap: wrap;
  padding: 20rpx 10rpx;
  
  .tag-item {
    display: inline-flex;
    align-items: center;
    padding: 10rpx 20rpx;
    margin: 10rpx;
    border-radius: 30rpx;
    background-color: #f8f8f8;
    border: 1px solid #e0e0e0;
    font-size: 28rpx;
    color: #333333;
    transition: all 0.2s ease;
    
    &.active {
      color: #ffffff;
      background-color: #007aff;
      border-color: #007aff;
    }
    
    .tag-count {
      margin-left: 6rpx;
      font-size: 0.9em;
      opacity: 0.8;
    }
  }
  
  // 为不同级别的标签设置默认样式
  .tag-level-0 {
    opacity: 0.8;
  }
  .tag-level-1 {
    opacity: 0.85;
  }
  .tag-level-2 {
    opacity: 0.9;
    font-weight: 500;
  }
  .tag-level-3 {
    opacity: 0.95;
    font-weight: 500;
  }
  .tag-level-4 {
    opacity: 1;
    font-weight: 600;
  }
}
</style>

这个基础组件实现了我们需要的核心功能:

  • 标签以流式布局展示,自动换行
  • 根据传入的level属性设置不同级别的样式
  • 支持自定义颜色和字体大小
  • 点击事件封装,可传递给父组件处理

标签数据处理

标签云组件的核心在于如何根据标签的权重/热度来设置不同的视觉效果。一般来说,我们会根据标签出现的频率或者其他自定义规则来计算权重。下面是一个简单的处理函数:

/**
 * 处理标签数据,计算每个标签的级别
 * @param {Array} tags 原始标签数据
 * @param {Number} levelCount 级别数量,默认为5
 * @return {Array} 处理后的标签数据
 */
function processTagData(tags, levelCount = 5) {
  if (!tags || tags.length === 0) return [];
  
  // 找出最大和最小count值
  let maxCount = 0;
  let minCount = Infinity;
  
  tags.forEach(tag => {
    if (tag.count > maxCount) maxCount = tag.count;
    if (tag.count < minCount) minCount = tag.count;
  });
  
  // 如果最大最小值相同,说明所有标签权重一样
  if (maxCount === minCount) {
    return tags.map(tag => ({
      ...tag,
      level: 0
    }));
  }
  
  // 计算每个标签的级别
  const countRange = maxCount - minCount;
  const levelStep = countRange / (levelCount - 1);
  
  return tags.map(tag => ({
    ...tag,
    level: Math.min(
      Math.floor((tag.count - minCount) / levelStep),
      levelCount - 1
    )
  }));
}

这个函数会根据标签的count属性,将所有标签分为0-4共5个级别,我们可以在使用组件前先对数据进行处理。

使用标签云组件

接下来,让我们看看如何在页面中使用这个组件:

<template>
  <view class="page-container">
    <view class="section-title">热门话题</view>
    <tag-cloud 
      :tags="processedTags" 
      :color-map="colorMap"
      :show-count="true"
      @click="onTagClick"
    ></tag-cloud>
  </view>
</template>

<script>
import TagCloud from '@/components/tag-cloud.vue';

export default {
  components: {
    TagCloud
  },
  data() {
    return {
      tags: [
        { name: '前端开发', count: 120 },
        { name: 'Vue', count: 232 },
        { name: 'UniApp', count: 180 },
        { name: '小程序', count: 156 },
        { name: 'React', count: 98 },
        { name: 'Flutter', count: 76 },
        { name: 'JavaScript', count: 210 },
        { name: 'CSS', count: 89 },
        { name: 'TypeScript', count: 168 },
        { name: '移动开发', count: 143 },
        { name: '云开发', count: 58 },
        { name: '性能优化', count: 112 }
      ],
      colorMap: ['#8a9aa9', '#61bfad', '#f8b551', '#ef6b73', '#e25c3d']
    }
  },
  computed: {
    processedTags() {
      // 调用上面定义的处理函数
      return this.processTagData(this.tags);
    }
  },
  methods: {
    processTagData(tags, levelCount = 5) {
      // 这里是上面定义的标签处理函数
      // ...函数内容同上...
    },
    onTagClick({ item, index }) {
      console.log(`点击了标签: ${item.name}, 索引: ${index}`);
      uni.showToast({
        title: `你选择了: ${item.name}`,
        icon: 'none'
      });
      
      // 这里可以进行页面跳转或其他操作
      // uni.navigateTo({
      //   url: `/pages/topic/topic?name=${encodeURIComponent(item.name)}`
      // });
    }
  }
}
</script>

<style lang="scss">
.page-container {
  padding: 30rpx;
  
  .section-title {
    font-size: 34rpx;
    font-weight: bold;
    margin-bottom: 20rpx;
    color: #333;
  }
}
</style>

进阶:随机颜色与布局

标签云还有一种常见的效果是随机颜色和随机大小。下面我们来实现这个功能:

// 在组件的methods中添加如下方法

// 获取随机颜色
getRandomColor() {
  const colors = [
    '#61bfad', '#f8b551', '#ef6b73', '#8a9aa9', 
    '#e25c3d', '#6cc0e5', '#fb6e50', '#f9cb8b'
  ];
  return colors[Math.floor(Math.random() * colors.length)];
},

// 修改getTagStyle方法
getTagStyle(item) {
  const style = {};
  
  if (this.random) {
    // 随机模式
    style.fontSize = `${Math.floor(Math.random() * 
      (this.maxFontSize - this.minFontSize) + this.minFontSize)}rpx`;
    style.color = this.getRandomColor();
    style.borderColor = style.color;
  } else {
    // 原有的level模式
    const level = item.level || 0;
    
    if (this.maxFontSize !== this.minFontSize) {
      const fontStep = (this.maxFontSize - this.minFontSize) / 4;
      style.fontSize = `${this.minFontSize + level * fontStep}rpx`;
    }
    
    if (this.colorMap.length > 0) {
      const colorIndex = Math.min(level, this.colorMap.length - 1);
      style.color = this.colorMap[colorIndex];
      style.borderColor = this.colorMap[colorIndex];
    }
  }
  
  return style;
}

然后在props中添加random属性:

// 添加到props中
random: {
  type: Boolean,
  default: false
}

这样,当设置 randomtrue 时,标签就会以随机颜色和大小展示,增加视觉的多样性。

实现可选中的标签云

在某些场景下,我们需要标签支持选中功能,比如在筛选器中。我们可以对组件进行扩展:

<template>
  <!-- 添加多选模式 -->
  <view class="tag-cloud-container">
    <view 
      v-for="(item, index) in internalTags" 
      :key="index"
      class="tag-item"
      :class="[
        `tag-level-${item.level || 0}`, 
        item.selected ? 'selected' : '',
        selectable ? 'selectable' : ''
      ]"
      :style="getTagStyle(item)"
      @tap="handleTagClick(item, index)"
    >
      <text>{{ item.name }}</text>
      <text v-if="showCount && item.count" class="tag-count">({{ item.count }})</text>
    </view>
  </view>
</template>

<script>
export default {
  // ... 现有代码 ...
  props: {
    // ... 现有props ...
    
    // 是否支持选中
    selectable: {
      type: Boolean,
      default: false
    },
    // 最大可选数量,0表示不限制
    maxSelectCount: {
      type: Number,
      default: 0
    },
    // 选中的标签值数组
    value: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      // 内部维护的标签数据,添加selected状态
      internalTags: []
    };
  },
  watch: {
    tags: {
      immediate: true,
      handler(newVal) {
        this.initInternalTags();
      }
    },
    value: {
      handler(newVal) {
        this.syncSelectedStatus();
      }
    }
  },
  methods: {
    // 初始化内部标签数据
    initInternalTags() {
      this.internalTags = this.tags.map(tag => ({
        ...tag,
        selected: this.value.includes(tag.name)
      }));
    },
    
    // 同步选中状态
    syncSelectedStatus() {
      if (!this.selectable) return;
      
      this.internalTags.forEach(tag => {
        tag.selected = this.value.includes(tag.name);
      });
    },
    
    // 修改标签点击处理逻辑
    handleTagClick(item, index) {
      if (this.selectable) {
        // 处理选中逻辑
        const newSelected = !item.selected;
        
        // 检查是否超出最大选择数量
        if (newSelected && this.maxSelectCount > 0) {
          const currentSelectedCount = this.internalTags.filter(t => t.selected).length;
          if (currentSelectedCount >= this.maxSelectCount) {
            uni.showToast({
              title: `最多只能选择${this.maxSelectCount}个标签`,
              icon: 'none'
            });
            return;
          }
        }
        
        // 更新选中状态
        this.$set(this.internalTags[index], 'selected', newSelected);
        
        // 构建新的选中值数组
        const selectedValues = this.internalTags
          .filter(tag => tag.selected)
          .map(tag => tag.name);
        
        // 触发input事件,支持v-model
        this.$emit('input', selectedValues);
      }
      
      // 触发点击事件
      this.$emit('click', { 
        item: this.internalTags[index], 
        index,
        selected: this.internalTags[index].selected
      });
    }
  }
}
</script>

<style lang="scss">
.tag-cloud-container {
  // ... 现有样式 ...
  
  .tag-item {
    // ... 现有样式 ...
    
    &.selectable {
      cursor: pointer;
      user-select: none;
      
      &:hover {
        opacity: 0.8;
      }
    }
    
    &.selected {
      color: #ffffff;
      background-color: #007aff;
      border-color: #007aff;
    }
  }
}
</style>

这样,我们的标签云就支持了多选模式,并且可以通过v-model进行双向绑定。

实战案例:兴趣标签选择器

最后,我们来看一个实际应用案例 - 用户注册时的兴趣标签选择:

<template>
  <view class="interest-selector">
    <view class="title">选择你感兴趣的话题</view>
    <view class="subtitle">选择3-5个你感兴趣的话题,我们将为你推荐相关内容</view>
    
    <tag-cloud
      :tags="interestTags"
      :selectable="true"
      :max-select-count="5"
      v-model="selectedInterests"
      @click="onInterestTagClick"
    ></tag-cloud>
    
    <view class="selected-count">
      已选择 {{ selectedInterests.length }}/5 个话题
    </view>
    
    <button 
      class="confirm-btn" 
      :disabled="selectedInterests.length < 3"
      @tap="confirmSelection"
    >
      确认选择
    </button>
  </view>
</template>

<script>
import TagCloud from '@/components/tag-cloud.vue';

export default {
  components: {
    TagCloud
  },
  data() {
    return {
      interestTags: [
        { name: '科技', count: 1250 },
        { name: '体育', count: 980 },
        { name: '电影', count: 1560 },
        { name: '音乐', count: 1320 },
        { name: '美食', count: 1480 },
        { name: '旅行', count: 1280 },
        { name: '摄影', count: 860 },
        { name: '游戏', count: 1420 },
        { name: '时尚', count: 760 },
        { name: '健身', count: 890 },
        { name: '阅读', count: 720 },
        { name: '动漫', count: 830 },
        { name: '宠物', count: 710 },
        { name: '财经', count: 680 },
        { name: '汽车', count: 590 },
        { name: '育儿', count: 520 },
        { name: '教育', count: 780 },
        { name: '历史', count: 650 }
      ],
      selectedInterests: []
    }
  },
  created() {
    // 处理标签数据,设置level
    this.interestTags = this.processTagData(this.interestTags);
  },
  methods: {
    processTagData(tags, levelCount = 5) {
      // ... 标签处理函数,同上 ...
    },
    onInterestTagClick({ item, selected }) {
      console.log(`${selected ? '选中' : '取消选中'}标签: ${item.name}`);
    },
    confirmSelection() {
      if (this.selectedInterests.length < 3) {
        uni.showToast({
          title: '请至少选择3个感兴趣的话题',
          icon: 'none'
        });
        return;
      }
      
      // 保存用户选择的兴趣标签
      uni.showLoading({
        title: '保存中...'
      });
      
      // 模拟API请求
      setTimeout(() => {
        uni.hideLoading();
        uni.showToast({
          title: '保存成功',
          icon: 'success'
        });
        
        // 跳转到首页
        setTimeout(() => {
          uni.reLaunch({
            url: '/pages/index/index'
          });
        }, 1500);
      }, 1000);
    }
  }
}
</script>

<style lang="scss">
.interest-selector {
  padding: 40rpx;
  
  .title {
    font-size: 40rpx;
    font-weight: bold;
    margin-bottom: 20rpx;
  }
  
  .subtitle {
    font-size: 28rpx;
    color: #666;
    margin-bottom: 50rpx;
  }
  
  .selected-count {
    text-align: center;
    margin: 30rpx 0;
    font-size: 28rpx;
    color: #666;
  }
  
  .confirm-btn {
    margin-top: 60rpx;
    background-color: #007aff;
    color: #fff;
    
    &[disabled] {
      background-color: #cccccc;
      color: #ffffff;
    }
  }
}
</style>

性能优化

当标签数量很多时,可能会遇到性能问题。以下是几个优化建议:

  1. 虚拟列表:对于特别多的标签(如上百个),可以考虑使用虚拟列表,只渲染可视区域内的标签。
  2. 懒加载:分批次加载标签,初始只加载一部分,用户滑动时再加载更多。
  3. 避免频繁重新渲染:减少不必要的标签状态更新,特别是在选中标签时。

下面是一个简单的虚拟列表实现思路:

// 在标签云组件中添加懒加载支持
props: {
  // ... 现有props ...
  lazyLoad: {
    type: Boolean,
    default: false
  },
  loadBatchSize: {
    type: Number,
    default: 20
  }
},
data() {
  return {
    // ... 现有data ...
    visibleTags: [],
    loadedCount: 0
  }
},
watch: {
  internalTags: {
    handler(newVal) {
      if (this.lazyLoad) {
        // 初始加载第一批
        this.loadMoreTags();
      } else {
        this.visibleTags = newVal;
      }
    },
    immediate: true
  }
},
methods: {
  // ... 现有methods ...
  
  loadMoreTags() {
    if (this.loadedCount >= this.internalTags.length) return;
    
    const nextBatch = this.internalTags.slice(
      this.loadedCount,
      this.loadedCount + this.loadBatchSize
    );
    
    this.visibleTags = [...this.visibleTags, ...nextBatch];
    this.loadedCount += nextBatch.length;
  },
  
  // 监听滚动到底部
  onScrollToBottom() {
    if (this.lazyLoad) {
      this.loadMoreTags();
    }
  }
}

然后在模板中使用 visibleTags 替代 internalTags,并监听滚动事件。

总结与优化建议

通过本文,我们实现了一个功能完善的标签云组件,它具有以下特点:

  1. 灵活的布局:自动换行,适应不同尺寸的屏幕
  2. 多样化的样式:支持根据标签热度/权重展示不同样式
  3. 交互功能:支持点击、选中等交互
  4. 性能优化:考虑了大数据量下的性能问题

实际应用中,还可以根据具体需求进行以下优化:

  1. 动画效果:添加标签hover/点击动画,提升用户体验
  2. 拖拽排序:支持拖拽调整标签顺序
  3. 搜索过滤:添加搜索框,快速筛选标签
  4. 分类展示:按类别分组展示标签
  5. 数据持久化:将用户选择的标签保存到本地或服务器

标签云组件看似简单,但能够在很多场景中发挥重要作用,比如:

  • 用户兴趣标签选择
  • 文章标签展示
  • 商品分类快速入口
  • 数据可视化展示
  • 关键词筛选器

希望这篇文章能够帮助你在UniApp中实现自己的标签云组件。如果有任何问题或改进建议,欢迎在评论区交流讨论!

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

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

相关文章

2025年渗透测试面试题总结-百度面经(题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 百度面经 百度安全工程师面试深度复盘与优化指南 一、项目经验反思与优化策略 二、技术问题深度解析 …

分别用 语言模型雏形N-Gram 和 文本表示BoW词袋 来实现文本情绪分类

语言模型的雏形 N-Gram 和简单文本表示 Bag-of-Words 语言表示模型简介 (1) Bag-of-Words (BoW) 是什么&#xff1f; *定义&#xff1a;将文本表示为词频向量&#xff0c;忽略词序和语法&#xff0c;仅记录每个词的出现次数。 **示例&#xff1a; 句子1&#xff1a;I love …

C#.NET 或 VB.NET Windows 窗体中的 DataGridView – 技巧、窍门和常见问题

DataGridView 控件是一个 Windows 窗体控件&#xff0c;它允许您自定义和编辑表格数据。它提供了许多属性、方法和事件来自定义其外观和行为。在本文中&#xff0c;我们将讨论一些常见问题及其解决方案。这些问题来自各种来源&#xff0c;包括一些新闻组、MSDN 网站以及一些由我…

PyTorch音频处理技术及应用研究:从特征提取到相似度分析

文章目录 音频处理技术及应用音频处理技术音视频摘要技术音频识别及应用 梅尔频率倒谱系数音频特征尔频率倒谱系数简介及参数提取过程音频处理快速傅里叶变换(FFT)能量谱处理离散余弦转换 练习案例&#xff1a;音频建模加载音频数据源波形变换的类型绘制波形频谱图波形Mu-Law 编…

VSTO(C#)Excel开发进阶2:操作图片 改变大小 滚动到可视区

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。 源码指引:github源码指引_初级代码游戏的博客-CSDN博客 入…

多用途商务,电子产品发布,科技架构,智能手表交互等发布PPT模版20套一组分享

产品发布类PPT模版20套一组&#xff1a;产品发布PPT模版https://pan.quark.cn/s/25c8517b0be3 第一套PPT模版是一个总结用的PPT封面&#xff0c;背景浅灰色&#xff0c;有绿色叶片和花朵装饰&#xff0c;深绿色标题&#xff0c;多个适用场景和占位符。突出其清新自然的设计和商…

WindowsPE文件格式入门11.资源表

https://www.bpsend.net/thread-411-1-1.html 资源表 资源的管理方式采用windows资源管理器目录的管理方式&#xff0c;一般有三层目录。根目录 结构体IMAGE_RESOURCE_DIRECTORY&#xff1a;描述名称资源和ID资源各自的数量&#xff0c;不描述文件。资源本质都是二进制数据&…

C语言标准I/O与Linux系统调用的文件操作

01. 标准库函数与系统调用对比 系统调用标准I/O库open/read/write/closefopen/fread/fwrite/fclose文件描述符(fd)文件指针(FILE*)无缓冲&#xff0c;直接系统调用自动缓冲管理每次操作触发系统调用减少系统调用次数<fcntl.h> <unistd.h><stdio.h> 系统调用…

【MYSQL】笔记

&#x1f4da; 博主的专栏 &#x1f427; Linux | &#x1f5a5;️ C | &#x1f4ca; 数据结构 | &#x1f4a1;C 算法 | &#x1f152; C 语言 | &#x1f310; 计算机网络 在ubuntu中&#xff0c;改配置文件&#xff1a; sudo nano /etc/mysql/mysql.conf.d/mysq…

线程池核心线程永续机制:从源码到实战的深度解析

简介 源管理的基石,其核心线程为何不会超时销毁一直是开发者关注的焦点。核心线程的永续机制不仅确保了系统的稳定响应,还避免了频繁创建和销毁线程带来的性能损耗。本文将从源码层面深入剖析线程池核心线程的存活原理,同时结合企业级实战案例,展示如何正确配置和管理线程…

DS新论文解读(2)

上一章忘了说论文名字了&#xff0c;是上图这个名字 我们继续&#xff0c;上一章阅读地址&#xff1a; dsv3新论文解读&#xff08;1&#xff09; 这论文剩下部分值得说的我觉得主要就是他们Infra通信的设计 先看一个图 这个是一个标准的h800 8卡with 8cx7 nic的图&#xf…

html文件cdn一键下载并替换

业务场景&#xff1a; AI生成的html文件&#xff0c;通常会使用多个cdn资源、手动替换or下载太过麻烦、如下py程序为此而生&#xff0c;指定html目录自动下载并替换~ import os import requests from bs4 import BeautifulSoup from urllib.parse import urlparse import has…

【ROS2】 核心概念6——通信接口语法(Interfaces)

古月21讲/2.6_通信接口 官方文档&#xff1a;Interfaces — ROS 2 Documentation: Humble documentation 官方接口代码实战&#xff1a;https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Single-Package-Define-And-Use-Interface.html ROS 2使用简化的描…

matlab官方免费下载安装超详细教程2025最新matlab安装教程(MATLAB R2024b)

文章目录 准备工作MATLAB R2024b 安装包获取详细安装步骤1. 文件准备2. 启动安装程序3. 配置安装选项4. 选择许可证文件5. 设置安装位置6. 选择组件7. 开始安装8. 完成辅助设置 常见问题解决启动失败问题 结语 准备工作 本教程将帮助你快速掌握MATLAB R2024b的安装技巧&#x…

【运营商查询】批量手机号码归属地和手机运营商高速查询分类,按省份城市,按运营商移动联通电信快速分类导出Excel表格,基于WPF的实现方案

WPF手机号码归属地批量查询与分类导出方案 应用场景 ​​市场营销​​&#xff1a;企业根据手机号码归属地进行精准营销&#xff0c;按城市或省份分类制定针对性推广策略​​客户管理​​&#xff1a;快速对客户手机号码进行归属地分类&#xff0c;便于后续客户关系管理​​数…

ctf 基础

一、软件安装和基本的网站&#xff1a; 网安招聘网站 xss跨站脚本攻击 逆向&#xff1a;可以理解为游戏里的外挂 pwn最难的题目 密码学&#xff1a; 1、编码&#xff1a;base64 2、加密&#xff1a;凯撒 3、摘要&#xff1a;MD5、SHA1、SHA2 调查取证&#xff1a;杂项&am…

CentOS7原有磁盘扩容实战记录(LVM非LVM)【针对GPT分区】

一、环境 二、命令及含义 fdisk ‌ ‌ fdisk‌是一个较老的分区表创建和管理工具&#xff0c;主要支持MBR&#xff08;Master Boot Record&#xff09;格式的分区表。MBR分区表支持的硬盘单个分区最大容量为2TB&#xff0c;最多可以有4个主分区。fdisk通过命令行界面进行操…

AI agent与lang chain的学习笔记 (1)

文章目录 智能体的4大要素一些上手的例子与思考。创建简单的AI agent.从本地读取文件&#xff0c;然后让AI智能体总结。 也可以自己定义一些工具 来完成一些特定的任务。我们可以使用智能体总结一个视频。用户可以随意问关于视频的问题。 智能体的4大要素 AI 智能体有以下几个…

谢赛宁团队提出 BLIP3-o:融合自回归与扩散模型的统一多模态架构,开创CLIP特征驱动的图像理解与生成新范式

BLIP3-o 是一个统一的多模态模型&#xff0c;它将自回归模型的推理和指令遵循优势与扩散模型的生成能力相结合。与之前扩散 VAE 特征或原始像素的研究不同&#xff0c;BLIP3-o 扩散了语义丰富的CLIP 图像特征&#xff0c;从而为图像理解和生成构建了强大而高效的架构。 此外还…

【idea】调试篇 idea调试技巧合集

前言&#xff1a;之前博主写过一篇idea技巧合集的文章&#xff0c;由于技巧过于多了&#xff0c;文章很庞大&#xff0c;所以特地将调试相关的技巧单独成章, 调试和我们日常开发是息息相关的&#xff0c;用好调试可以事半功倍 文章目录 1. idea调试异步线程2. idea调试stream流…