Tailwind CSS 实战:社交媒体信息流开发

在社交媒体的世界里,信息流就像是一条永不停歇的河流,承载着用户的分享与互动。记得在一个社交平台项目中,我们通过重新设计信息流的展示方式,让用户的平均浏览时长提升了 45%。今天,我想和大家分享如何使用 Tailwind CSS 打造一个引人入胜的社交媒体信息流。

设计理念

设计社交媒体信息流就像是在策划一场永不落幕的展览。每一条动态都是一件展品,需要精心布置,让观众(用户)能够轻松浏览,并产生互动的欲望。在这个展览中,我们不仅要关注单个展品的呈现,更要考虑整体的节奏和韵律。

想象一下,当用户打开应用时,他们就像是走进了一个充满故事的长廊。有趣的图文内容是装点墙面的画作,短视频是播放的影像,而评论区则是观众的留言板。这种沉浸式的体验,需要我们在设计时特别注意以下几点:

  1. 内容呈现要像是精心策划的展位,让每条信息都有自己的舞台
  2. 交互设计要像是无声的导览,引导用户自然地浏览和参与
  3. 性能优化要像是通风系统,在用户无感知的情况下保持体验的流畅

信息流卡片开发

信息流卡片是整个展览中最基础的展示单元,需要像艺术品展架一样,既要突出内容,又要保持整体的协调:

<div class="max-w-2xl mx-auto">
  <!-- 信息流卡片 -->
  <article class="bg-white rounded-lg shadow-sm mb-6 overflow-hidden">
    <!-- 用户信息区 -->
    <div class="flex items-center px-4 py-3">
      <div class="flex items-center">
        <!-- 头像 -->
        <img 
          class="h-10 w-10 rounded-full object-cover border-2 border-white shadow-sm"
          src="/avatars/user-1.jpg" 
          alt="用户头像"
        >
        <!-- 用户名和发布时间 -->
        <div class="ml-3">
          <h3 class="text-sm font-semibold text-gray-900">
            <a href="#" class="hover:underline">摄影师小王</a>
          </h3>
          <span class="text-xs text-gray-500">2小时前 · 上海</span>
        </div>
      </div>
      <!-- 更多操作按钮 -->
      <button class="ml-auto p-2 hover:bg-gray-100 rounded-full">
        <svg class="h-5 w-5 text-gray-500" fill="currentColor" viewBox="0 0 20 20">
          <path d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" />
        </svg>
      </button>
    </div>

    <!-- 内容区域 -->
    <div class="px-4 py-2">
      <p class="text-gray-900 text-sm">
        今天在外滩拍到的日落,光线真的太美了!分享给大家 ✨
        <a href="#" class="text-blue-600 hover:underline">#上海风光</a>
        <a href="#" class="text-blue-600 hover:underline">#摄影日常</a>
      </p>
    </div>

    <!-- 图片区域 -->
    <div class="mt-2">
      <div class="grid grid-cols-2 gap-1">
        <div class="relative aspect-w-1 aspect-h-1">
          <img 
            src="/photos/sunset-1.jpg" 
            alt="日落照片" 
            class="w-full h-full object-cover cursor-pointer hover:opacity-95 transition-opacity"
            οnclick="openLightbox(this.src)"
          >
        </div>
        <div class="relative aspect-w-1 aspect-h-1">
          <img 
            src="/photos/sunset-2.jpg" 
            alt="日落照片" 
            class="w-full h-full object-cover cursor-pointer hover:opacity-95 transition-opacity"
            οnclick="openLightbox(this.src)"
          >
        </div>
      </div>
    </div>

    <!-- 互动区域 -->
    <div class="px-4 py-3">
      <!-- 点赞、评论、分享按钮 -->
      <div class="flex items-center space-x-4">
        <button class="flex items-center space-x-2 text-gray-600 hover:text-red-500 transition-colors">
          <svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" />
          </svg>
          <span class="text-sm">1,234</span>
        </button>
        <button class="flex items-center space-x-2 text-gray-600 hover:text-blue-500 transition-colors">
          <svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
          </svg>
          <span class="text-sm">89</span>
        </button>
        <button class="flex items-center space-x-2 text-gray-600 hover:text-green-500 transition-colors">
          <svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.368 2.684 3 3 0 00-5.368-2.684z" />
          </svg>
          <span class="text-sm">46</span>
        </button>
      </div>

      <!-- 评论预览 -->
      <div class="mt-3 space-y-3">
        <div class="flex space-x-2">
          <a href="#" class="text-sm font-medium text-gray-900 hover:underline">摄影师老李</a>
          <p class="text-sm text-gray-600">构图很赞,光线把握得恰到好处!</p>
        </div>
        <div class="flex space-x-2">
          <a href="#" class="text-sm font-medium text-gray-900 hover:underline">设计师小张</a>
          <p class="text-sm text-gray-600">色彩层次感很强,期待更多作品!</p>
        </div>
        <!-- 查看更多评论 -->
        <button class="text-sm text-gray-500 hover:text-gray-700">
          查看全部 89 条评论
        </button>
      </div>

      <!-- 评论输入框 -->
      <div class="mt-3 flex items-center">
        <img 
          class="h-8 w-8 rounded-full object-cover"
          src="/avatars/current-user.jpg" 
          alt="当前用户头像"
        >
        <div class="flex-1 ml-3">
          <input 
            type="text" 
            placeholder="添加评论..." 
            class="w-full text-sm border-0 focus:ring-0 outline-none bg-transparent"
          >
        </div>
        <button class="ml-2 text-sm font-medium text-blue-500 hover:text-blue-600">
          发布
        </button>
      </div>
    </div>
  </article>
</div>

<!-- 图片预览弹窗 -->
<div id="lightbox" class="fixed inset-0 bg-black bg-opacity-90 hidden z-50">
  <button class="absolute top-4 right-4 text-white" οnclick="closeLightbox()">
    <svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
    </svg>
  </button>
  <img 
    id="lightbox-image" 
    class="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 max-w-[90vw] max-h-[90vh]"
    src="" 
    alt="预览图片"
  >
</div>

<script>
function openLightbox(src) {
  const lightbox = document.getElementById('lightbox');
  const lightboxImage = document.getElementById('lightbox-image');
  lightboxImage.src = src;
  lightbox.classList.remove('hidden');
  document.body.style.overflow = 'hidden';
}

function closeLightbox() {
  const lightbox = document.getElementById('lightbox');
  lightbox.classList.add('hidden');
  document.body.style.overflow = '';
}
</script>

无限滚动实现

无限滚动就像是展览的自动导览系统,需要在适当的时机加载新的内容:

<div id="feed-container" class="max-w-2xl mx-auto">
  <!-- 信息流内容 -->
  <div id="feed-content">
    <!-- 动态卡片将在这里动态插入 -->
  </div>

  <!-- 加载状态 -->
  <div id="loading-indicator" class="py-4 text-center hidden">
    <div class="inline-flex items-center px-4 py-2 font-semibold leading-6 text-sm shadow rounded-md text-white bg-indigo-500 transition ease-in-out duration-150 cursor-not-allowed">
      <svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-white" fill="none" viewBox="0 0 24 24">
        <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
        <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
      </svg>
      正在加载更多...
    </div>
  </div>
</div>

<script>
// 使用 Intersection Observer 实现无限滚动
let page = 1;
let loading = false;

const loadMorePosts = async () => {
  if (loading) return;

  loading = true;
  document.getElementById('loading-indicator').classList.remove('hidden');

  try {
    const response = await fetch(`/api/posts?page=${page}`);
    const posts = await response.json();

    if (posts.length > 0) {
      // 渲染新的帖子
      posts.forEach(post => {
        const postElement = createPostElement(post);
        document.getElementById('feed-content').appendChild(postElement);
      });
      page++;
    }
  } catch (error) {
    console.error('加载失败:', error);
  } finally {
    loading = false;
    document.getElementById('loading-indicator').classList.add('hidden');
  }
};

// 创建观察器
const observer = new IntersectionObserver((entries) => {
  const lastEntry = entries[0];
  if (lastEntry.isIntersecting) {
    loadMorePosts();
  }
}, {
  rootMargin: '100px'
});

// 监听加载指示器
observer.observe(document.getElementById('loading-indicator'));

// 创建帖子元素的辅助函数
function createPostElement(post) {
  const template = document.createElement('template');
  template.innerHTML = `
    <article class="bg-white rounded-lg shadow-sm mb-6 overflow-hidden">
      <!-- 帖子内容模板 -->
    </article>
  `;
  return template.content.firstElementChild;
}
</script>

故事流实现

故事流就像是展览中的特别展区,需要吸引眼球并鼓励互动:

<div class="max-w-2xl mx-auto mb-6">
  <div class="relative">
    <!-- 故事列表 -->
    <div class="flex space-x-4 overflow-x-auto pb-4 scrollbar-hide">
      <!-- 添加故事按钮 -->
      <div class="flex-shrink-0 w-20">
        <div class="relative group cursor-pointer">
          <div class="w-16 h-16 rounded-full overflow-hidden border-2 border-dashed border-gray-300 flex items-center justify-center bg-gray-50 group-hover:bg-gray-100">
            <svg class="h-8 w-8 text-gray-400 group-hover:text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
            </svg>
          </div>
          <p class="mt-1 text-xs text-center text-gray-500">添加故事</p>
        </div>
      </div>

      <!-- 故事项目 -->
      <div class="flex-shrink-0 w-20">
        <div class="relative group cursor-pointer" οnclick="openStory(1)">
          <div class="w-16 h-16 rounded-full overflow-hidden border-2 border-gradient-to-r from-pink-500 via-red-500 to-yellow-500">
            <img 
              src="/stories/story-1.jpg" 
              alt="故事封面" 
              class="w-full h-full object-cover"
            >
          </div>
          <p class="mt-1 text-xs text-center text-gray-900 truncate">旅行日记</p>
        </div>
      </div>
      <!-- 更多故事... -->
    </div>

    <!-- 左右滚动按钮 -->
    <button class="absolute left-0 top-1/2 transform -translate-y-1/2 bg-white rounded-full shadow-lg p-2 hover:bg-gray-50 focus:outline-none hidden md:block">
      <svg class="h-5 w-5 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" />
      </svg>
    </button>
    <button class="absolute right-0 top-1/2 transform -translate-y-1/2 bg-white rounded-full shadow-lg p-2 hover:bg-gray-50 focus:outline-none hidden md:block">
      <svg class="h-5 w-5 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
      </svg>
    </button>
  </div>
</div>

<!-- 故事查看器 -->
<div id="story-viewer" class="fixed inset-0 bg-black hidden z-50">
  <div class="relative h-full">
    <!-- 故事内容 -->
    <div class="absolute inset-0">
      <img 
        id="story-image" 
        class="w-full h-full object-contain"
        src="" 
        alt="故事内容"
      >
    </div>

    <!-- 进度条 -->
    <div class="absolute top-0 left-0 right-0 flex space-x-1 p-2">
      <div class="flex-1 h-0.5 bg-white bg-opacity-30">
        <div class="h-full bg-white w-0" style="animation: progress 5s linear forwards;"></div>
      </div>
    </div>

    <!-- 用户信息 -->
    <div class="absolute top-4 left-4 flex items-center">
      <img 
        class="h-8 w-8 rounded-full border-2 border-white"
        src="/avatars/story-user.jpg" 
        alt="用户头像"
      >
      <div class="ml-2 text-white">
        <h4 class="text-sm font-semibold">用户昵称</h4>
        <p class="text-xs opacity-75">2小时前</p>
      </div>
    </div>

    <!-- 关闭按钮 -->
    <button class="absolute top-4 right-4 text-white" οnclick="closeStory()">
      <svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
      </svg>
    </button>
  </div>
</div>

<style>
@keyframes progress {
  from { width: 0; }
  to { width: 100%; }
}

.scrollbar-hide {
  -ms-overflow-style: none;
  scrollbar-width: none;
}
.scrollbar-hide::-webkit-scrollbar {
  display: none;
}
</style>

<script>
function openStory(id) {
  const viewer = document.getElementById('story-viewer');
  const image = document.getElementById('story-image');
  image.src = `/stories/story-${id}-full.jpg`;
  viewer.classList.remove('hidden');
  document.body.style.overflow = 'hidden';
}

function closeStory() {
  const viewer = document.getElementById('story-viewer');
  viewer.classList.add('hidden');
  document.body.style.overflow = '';
}
</script>

动态更新效果

动态更新就像是展览的实时互动,需要平滑而自然:

<script>
// 点赞动画
function animateLike(button) {
  // 创建心形图标
  const heart = document.createElement('div');
  heart.innerHTML = `
    <svg class="h-16 w-16 text-red-500 transform scale-0 opacity-0 transition-all duration-500" 
         fill="currentColor" viewBox="0 0 20 20">
      <path fill-rule="evenodd" 
            d="M3.172 5.172a4 4 0 015.656 0L10 6.343l1.172-1.171a4 4 0 115.656 5.656L10 17.657l-6.828-6.829a4 4 0 010-5.656z" 
            clip-rule="evenodd" />
    </svg>
  `;

  // 定位动画
  heart.style.position = 'absolute';
  heart.style.top = '50%';
  heart.style.left = '50%';
  heart.style.transform = 'translate(-50%, -50%)';
  button.appendChild(heart);

  // 播放动画
  requestAnimationFrame(() => {
    const svg = heart.querySelector('svg');
    svg.classList.remove('scale-0', 'opacity-0');
    svg.classList.add('scale-100', 'opacity-100');

    setTimeout(() => {
      svg.classList.add('scale-0', 'opacity-0');
      setTimeout(() => heart.remove(), 500);
    }, 1000);
  });
}

// 评论实时更新
function addComment(postId, comment) {
  const commentsList = document.querySelector(`#post-${postId} .comments-list`);
  const newComment = document.createElement('div');
  newComment.classList.add('flex', 'space-x-2', 'animate-fade-in');
  newComment.innerHTML = `
    <a href="#" class="text-sm font-medium text-gray-900 hover:underline">
      ${comment.userName}
    </a>
    <p class="text-sm text-gray-600">${comment.content}</p>
  `;

  commentsList.insertBefore(newComment, commentsList.firstChild);
}

// 动态加载动画
class LoadingAnimation {
  constructor(element) {
    this.element = element;
    this.dots = 0;
    this.interval = null;
  }

  start() {
    this.interval = setInterval(() => {
      this.dots = (this.dots + 1) % 4;
      this.element.textContent = '加载中' + '.'.repeat(this.dots);
    }, 300);
  }

  stop() {
    clearInterval(this.interval);
    this.element.textContent = '';
  }
}
</script>

<style>
@keyframes fade-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

.animate-fade-in {
  animation: fade-in 0.3s ease-out forwards;
}
</style>

性能优化

在社交媒体信息流中,性能优化就像是展览的后勤保障,需要在用户无感知的情况下保持流畅:

<script>
// 虚拟列表实现
class VirtualList {
  constructor(container, items, rowHeight) {
    this.container = container;
    this.items = items;
    this.rowHeight = rowHeight;
    this.visibleItems = Math.ceil(container.clientHeight / rowHeight) + 2;
    this.scrollTop = 0;
    this.startIndex = 0;

    this.init();
  }

  init() {
    // 设置容器高度
    this.container.style.height = `${this.items.length * this.rowHeight}px`;

    // 创建视口
    this.viewport = document.createElement('div');
    this.viewport.style.position = 'relative';
    this.viewport.style.overflow = 'hidden';
    this.container.appendChild(this.viewport);

    // 监听滚动
    this.container.addEventListener('scroll', this.onScroll.bind(this));

    // 初始渲染
    this.render();
  }

  onScroll() {
    this.scrollTop = this.container.scrollTop;
    this.render();
  }

  render() {
    // 计算可见区域的起始索引
    this.startIndex = Math.floor(this.scrollTop / this.rowHeight);
    const endIndex = Math.min(
      this.startIndex + this.visibleItems,
      this.items.length
    );

    // 清空视口
    this.viewport.innerHTML = '';

    // 渲染可见项
    for (let i = this.startIndex; i < endIndex; i++) {
      const item = this.items[i];
      const element = this.createItemElement(item);
      element.style.position = 'absolute';
      element.style.top = `${i * this.rowHeight}px`;
      this.viewport.appendChild(element);
    }
  }

  createItemElement(item) {
    // 创建列表项元素
    const element = document.createElement('div');
    element.style.height = `${this.rowHeight}px`;
    element.innerHTML = item.content;
    return element;
  }
}

// 图片懒加载优化
const imageObserver = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src;
      img.classList.remove('lazy');
      imageObserver.unobserve(img);
    }
  });
}, {
  rootMargin: '50px 0px'
});

document.querySelectorAll('img.lazy').forEach(img => {
  imageObserver.observe(img);
});

// 防抖动优化
function debounce(func, wait) {
  let timeout;
  return function executedFunction(...args) {
    const later = () => {
      clearTimeout(timeout);
      func(...args);
    };
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
}

// 应用防抖
const debouncedScroll = debounce(() => {
  // 滚动处理逻辑
}, 150);

window.addEventListener('scroll', debouncedScroll);

// 预加载优化
const preloadImages = () => {
  const images = document.querySelectorAll('[data-preload]');
  const imageUrls = Array.from(images).map(img => img.dataset.src);

  imageUrls.forEach(url => {
    const img = new Image();
    img.src = url;
  });
};

// DOM 回收优化
class DOMRecycler {
  constructor(container, template) {
    this.container = container;
    this.template = template;
    this.pool = [];
  }

  acquire() {
    return this.pool.pop() || this.template.cloneNode(true);
  }

  release(element) {
    element.remove();
    this.pool.push(element);
  }

  clear() {
    this.pool = [];
  }
}
</script>

写在最后

通过这篇文章,我们详细探讨了如何使用 Tailwind CSS 构建一个现代化的社交媒体信息流。从信息流卡片到故事流展示,从无限滚动到性能优化,我们不仅关注了视觉效果,更注重了用户体验和交互设计。

记住,一个优秀的社交媒体信息流就像是一场精心策划的展览,需要在内容呈现、交互体验和性能优化之间找到完美的平衡。在实际开发中,我们要始终以用户需求为中心,打造一个能够吸引用户驻足的数字展览。

如果觉得这篇文章对你有帮助,别忘了点个赞 👍

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[论文粗读]A Simple Framework for Contrastive Learning of Visual Representations

引言 今天带来一篇经典论文A Simple Framework for Contrastive Learning of Visual Representations的笔记。 本篇工作提出了SimCLR&#xff0c;一种用于视觉表征对比学习的简单框架。提出(1)数据增强组合在定义有效预测任务中起到至关重要的作用&#xff1b;(2)在表示和对比…

(leetcode算法题)188. 买卖股票的最佳时机 IV

题目中要求最多可以完成k次交易&#xff0c;很多时候不要把问题搞复杂了&#xff0c; 按照题目要求&#xff0c;研究对象是最后一天结束后最多进行了 k 次交易获得的最大利润 那么就可以把问题拆分成 第 1 天结束后完成 0 次交易获得的最大利润&#xff0c;第 1 天结束后完成…

使用 Docker 搭建 Hadoop 集群

1.1. 启用 WSL 与虚拟机平台 1.1.1. 启用功能 启用 WSL并使用 Moba 连接-CSDN博客 1.2 安装 Docker Desktop 最新版本链接&#xff1a;Docker Desktop: The #1 Containerization Tool for Developers | Docker 指定版本链接&#xff1a;Docker Desktop release notes | Do…

win32汇编环境,对话框程序模版,含文本框与菜单简单功能

;运行效果 ;win32汇编环境,对话框程序模版&#xff0c;含文本框与菜单简单功能 ;直接抄进RadAsm可编译运行。 ;下面为asm文件 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>&g…

【赵渝强老师】MongoDB文档级别的并发控制

MongoDB在执行写操作时&#xff0c;WiredTiger存储引擎会在文档级别进行并发控制。换句话说在同一时间点上&#xff0c;多个写操作能够修改同一个集合中的不同文档&#xff1b;而当多个写操作修改同一个文档时&#xff0c;必须以序列化方式执行。这意味着如果当前文档正在被修改…

Java开发 PDF文件生成方案

业务需求背景 业务端需要能够将考试答卷内容按指定格式呈现并导出为pdf格式进行存档&#xff0c;作为紧急需求插入。导出内容存在样式复杂性&#xff0c;包括特定的字体&#xff08;中文&#xff09;、字号、颜色&#xff0c;页面得有页眉、页码&#xff0c;数据需要进行表格聚…

C++文件流 例题

问题&#xff1a; 设计一个留言类&#xff0c;实现以下的功能&#xff1a; 1) 程序第一次运行时&#xff0c;建立一个 message.txt 文本文件&#xff0c;并把用 户输入的信息存入该文件&#xff1b; 2) 以后每次运行时&#xff0c;都先读取该文件的内容并显示给用户&#xf…

Xilinx DCI技术

Xilinx DCI技术 DCI技术概述Xilinx DCI技术实际使用某些Bank特殊DCI要求 DCI级联技术DCI端接方式阻抗控制驱动器&#xff08;源端接&#xff09;半阻抗控制阻抗驱动器&#xff08;源端接&#xff09;分体式DCI&#xff08;戴维宁等效端接到VCCO/2&#xff09;DCI和三态DCI&…

「Mac畅玩鸿蒙与硬件51」UI互动应用篇28 - 模拟记账应用

本篇教程将介绍如何创建一个模拟记账应用&#xff0c;通过账单输入、动态列表展示和实时统计功能&#xff0c;学习接口定义和组件间的数据交互。 关键词 UI互动应用接口定义动态列表实时统计数据交互 一、功能说明 模拟记账应用包含以下功能&#xff1a; 账单输入&#xff1…

阴阳师の新手如何速刷5个SP/SSR?!(急速育成)

目标&#xff1a;攒5个SP/SSR式神&#xff0c;参与急速育成&#xff0c;省四个黑蛋&#xff08;想要快速升级技能而且经常上场的式神在攒够5个式神前先不升级&#xff09;【理论上组成&#xff1a;10蓝40蓝预约召唤福利20修行or抽卡】 关键点&#xff1a;蓝票&#xff0c;新手…

Linux应用软件编程-多任务处理(进程,线程)-通信(管道,信号,内存共享)

多任务处理&#xff1a;让系统具备同时处理多个事件的能力。让系统具备并发性能。方法&#xff1a;进程和线程。这里先讲进程。 进程&#xff08;process&#xff09;&#xff1a;正在执行的程序&#xff0c;执行过程中需要消耗内存和CPU。 进程的创建&#xff1a;操作系统在…

使用 TensorFlow 打造企业智能数据分析平台

文章目录 摘要引言平台架构设计核心架构技术栈选型 数据采集与预处理代码详解 数据分析与预测代码详解 数据可视化ECharts 配置 总结未来展望参考资料 摘要 在大数据时代&#xff0c;企业决策正越来越依赖数据分析。然而&#xff0c;面对海量数据&#xff0c;传统分析工具常因…

初始JavaEE篇 —— Maven相关配置

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;JavaEE 目录 介绍 创建第一个Maven项目 Maven的核心功能 项目构建 依赖管理 添加依赖 依赖排除 依赖调解 Maven仓库 配置本地仓…

Linux套接字通信学习

Linux套接字通信 代码源码&#xff1a;https://github.com/say-Hai/TcpSocketLearn/tree/CThreadSocket 在网络通信的时候, 程序猿需要负责的应用层数据的处理(最上层)&#xff0c;而底层的数据封装与解封装&#xff08;如TCP/IP协议栈的功能&#xff09;通常由操作系统、网络协…

职场常用Excel基础01-数据验证

大家好&#xff0c;excel在职场中使用非常频繁&#xff0c;今天和大家一起分享一下excel中数据验证相关的内容~ 在Excel中&#xff0c;数据验证&#xff08;Data Validation&#xff09;是一项非常有用的功能&#xff0c;它可以帮助用户限制输入到单元格中的数据类型和范围&am…

建造者设计模式学习

1.介绍 建造者模式是一种创建型设计模式&#xff0c;它将一个复杂对象的构建过程与它的表示分离&#xff0c;使得相同的构建过程可以创建不同的表示。通过分步骤地构建对象&#xff0c;建造者模式提供了更细粒度的控制和灵活性&#xff0c;特别适合需要灵活创建复杂对象的场景…

ROS2+OpenCV综合应用--10. AprilTag标签码追踪

1. 简介 apriltag标签码追踪是在apriltag标签码识别的基础上&#xff0c;增加了小车摄像头云台运动的功能&#xff0c;摄像头会保持标签码在视觉中间而运动&#xff0c;根据这一特性&#xff0c;从而实现标签码追踪功能。 2. 启动 2.1 程序启动前的准备 本次apriltag标签码使…

mysql乱码、mysql数据中文问号

网上排出此错误方法的很多&#xff0c;但是 都不简洁&#xff0c;找不到根本原因 主要排查两点&#xff1a; 1.代码中jdbc链接的编码规则 urljdbc:mysql://localhost:3306/title?useUnicodetrue&amp;characterEncodingutf8 将characterEncoding设置为utf8 2.设置mysq…

Presto-简单了解-230403

presto是什么了解一下&#xff1a; 秒级查询引擎&#xff08;不做存储&#xff09;&#xff0c;GB-PB级不依赖于yarn&#xff0c;有自己的资源管理和执行计划支持多种数据源&#xff1a;hive、redis、kafka presto架构 presto优缺点 presto优点 内存到内存的传输&#xff0…

openGauss连接是报org.opengauss.util.PSQLException: 尝试连线已失败

安装好高斯数据库后然后用java连接时报如下错误: 解决方法: 在openGauss数据库的安装路径下/opt/opengauss/data/single_node&#xff08;这个路径根据自己实际情况变化&#xff09;有个pg_hba.conf文件&#xff0c;修改里面host内容如下&#xff0c;我这里设置的是所有ip都能…