前端(Vue)tagsView(子标签页视图切换) 原理及通用解决方案

news2024/11/16 11:44:16

文章目录

  • tagsView 方案总结
  • tagsView 原理分析
  • 创建 tags 数据源
  • 生成 tagsView
  • tagsView 国际化处理
  • contextMenu 展示处理
  • contextMenu 事件处理
  • 处理 contextMenu 的关闭行为
  • 处理基于路由的动态过渡

tagsView 方案总结

整个 tagsView 整体来看就是三块大的内容:

  1. tagstagsView 组件
  2. contextMenucontextMenu 组件
  3. viewappmain 组件

再加上一部分的数据处理(Vuex)即可。

tagsView 原理分析

tagsView 可以分成两部分来去看:

  1. tags
  2. view

image.png
image.png
可以把这两者分开。tags 仅仅就是很简单的 tag 组件。
脱离了 tags 只看 views 就更简单了,所谓 views指的就是一个用来渲染组件的位置容器。

  1. 动画
  2. (数据)缓存

加上这两个功能之后可能会略显复杂,但是 官网已经帮助我们处理了这个问题
image.png
再把tagsview 合并起来思考。
实现方案:

  1. 创建 tagsView 组件:用来处理 tags 的展示
  2. 处理基于路由的动态过渡,在 tags 区域中进行:用于处理 view 的部分

整个的方案就是这么两大部,但是其中还需要处理一些细节相关的。
完整的方案为

  1. 监听路由变化,组成用于渲染 tags 的数据源
  2. 创建 tags 组件,根据数据源渲染 tag,渲染出来的 tags 需要同时具备
    1. 国际化 title
    2. 路由跳转
  3. 处理鼠标右键效果,根据右键处理对应数据源

image.png

  1. 处理基于路由的动态过渡

创建 tags 数据源

tags 的数据源分为两部分:

  1. 保存数据:视图层父级 组件中进行
  2. 展示数据:tags 组件中进行

所以 tags 的数据我们最好把它保存到 vuex 中(及localStorage)
创建 tags 数据源:监听路由的变化,监听到的路由保存到 Tags 数据中。

创建 tagsViewList

import { LANG, TAGS_VIEW } from '@/constant'
import { getItem, setItem } from '@/utils/storage'
export default {
  namespaced: true,
  state: () => ({
    ...
      tagsViewList: getItem(TAGS_VIEW) || []
  }),
  mutations: {
    ...
      /**
     * 添加 tags
     */
      addTagsViewList(state, tag) {
      const isFind = state.tagsViewList.find(item => {
      return item.path === tag.path
    })
  // 处理重复【添加 tags,不要重复添加,因为用户可能会切换已经存在的 tag】
    if (!isFind) {
      state.tagsViewList.push(tag)
      setItem(TAGS_VIEW, state.tagsViewList)
    }
  }
},
actions: {}
}

视图层父级组件中监听路由的变化 (动态添加tag)
注意:并不是所有的路由都需要保存的,比如登录页面、404等
判断是否需要,创建工具函数 =>

const whiteList = ['/login', '/import', '/404', '/401']

/**
 * path 是否需要被缓存
 * @param {*} path
 * @returns
 */
export function isTags(path) {
  return !whiteList.includes(path)
}

image.png

<script setup>
import { watch } from 'vue'
import { isTags } from '@/utils/tags'
import { generateTitle } from '@/utils/i18n'
import { useRoute } from 'vue-router'
import { useStore } from 'vuex'

const route = useRoute()

/**
 * 生成 title
 */
const getTitle = route => {
  let title = ''
  if (!route.meta) {
    // 处理无 meta 的路由,路径中最后一个元素作为title
    const pathArr = route.path.split('/')
    title = pathArr[pathArr.length - 1]
  } else {
    // 包含meta的,直接国际化处理即可
    title = generateTitle(route.meta.title)
  }
  return title
}

/**
 * 监听路由变化
 */
const store = useStore()
watch(
  route,
  (to, from) => {
    if (!isTags(to.path)) return
    // 保存需要保存的路由属性
    const { fullPath, meta, name, params, path, query } = to
    store.commit('app/addTagsViewList', {
      fullPath,
      meta,
      name,
      params,
      path,
      query,
      title: getTitle(to)
    })
  },
  {
    // 组件初始化的时候也需被执行一次
    immediate: true
  }
)
</script>

生成 tagsView

创建 storetagsViewList 的快捷访问 (getters)

const getters = {
  token: state => state.user.token,
  //...
  tagsViewList: state => state.app.tagsViewList
}
export default getters

image.png

<template>
  <div class="tags-view-container">
    <!-- 每个tag页面就对应一个router-link -->
    <!-- router-link 有两种状态,一种是被选中的,另一种是不被选中的。绑定一个动态class =>  isActive(tag)  -->
    <!-- 如果是当前被选中的这一项,它的颜色应该是当前的主题色。添加样式即可。 -->
    <!-- to表示link跳转的地址 -->
      <router-link
        class="tags-view-item"
        :class="isActive(tag) ? 'active' : ''"  
        :style="{
          backgroundColor: isActive(tag) ? $store.getters.cssVar.menuBg : '',
          borderColor: isActive(tag) ? $store.getters.cssVar.menuBg : ''
        }"
        v-for="(tag, index) in $store.getters.tagsViewList"
        :key="tag.fullPath"
        :to="{ path: tag.fullPath }"
      >
        {{ tag.title }}
        <!-- 未被选中的tag上出现一个X号 -->
        <i
          v-show="!isActive(tag)"
          class="el-icon-close"
          @click.prevent.stop="onCloseClick(index)"
        />
      </router-link>
  </div>
</template>

<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()

/**
 * 是否被选中
 */
const isActive = tag => {
  return tag.path === route.path
}

/**
 * 关闭 tag 的点击事件
 */
const onCloseClick = index => {}
</script>

<style lang="scss" scoped>
.tags-view-container {
  height: 34px;
  width: 100%;
  background: #fff;
  border-bottom: 1px solid #d8dce5;
  box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 0 3px 0 rgba(0, 0, 0, 0.04);
    .tags-view-item {
      display: inline-block;
      position: relative;
      cursor: pointer;
      height: 26px;
      line-height: 26px;
      border: 1px solid #d8dce5;
      color: #495060;
      background: #fff;
      padding: 0 8px;
      font-size: 12px;
      margin-left: 5px;
      margin-top: 4px;
      &:first-of-type {
        margin-left: 15px;
      }
      &:last-of-type {
        margin-right: 15px;
      }
      &.active {
        color: #fff;
        &::before {
          content: '';
          background: #fff;
          display: inline-block;
          width: 8px;
          height: 8px;
          border-radius: 50%;
          position: relative;
          margin-right: 4px;
        }
      }
      // close 按钮
      .el-icon-close {
        width: 16px;
        height: 16px;
        line-height: 10px;
        vertical-align: 2px;
        border-radius: 50%;
        text-align: center;
        transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
        transform-origin: 100% 50%;
        &:before {
          transform: scale(0.6);
          display: inline-block;
          vertical-align: -3px;
        }
        &:hover {
          background-color: #b4bccc;
          color: #fff;
        }
      }
    
  }
}
</style>

tagsView 国际化处理

tagsView 的国际化处理可以理解为修改现有 tagstitle
tags的数据都保存在了tagsViewList,它里的tile是啥类型语言,tag这里的名字就应该显示啥语言。
=>

  1. 监听到语言变化
  2. 国际化对应的 title 即可

store 中,创建修改 ttilemutations
给某个tag修改title,只需要触发该mutation即可。

/**
* 为指定的 tag 修改 title
*/
changeTagsView(state, { index, tag }) {
  state.tagsViewList[index] = tag // 更新最新的tag
  setItem(TAGS_VIEW, state.tagsViewList)
}

在 路由视图的父组件 中监听语言变化

import { generateTitle, watchSwitchLang } from '@/utils/i18n'
/**
 * 国际化 tags
 */
watchSwitchLang(() => {
  store.getters.tagsViewList.forEach((route, index) => {
    store.commit('app/changeTagsView', {
      index,
      tag: {
        ...route,  // 解构route,覆盖掉title即可,其他不变
        title: getTitle(route)
      }
    })
  })
})

contextMenu 展示处理

image.png
contextMenu 为 鼠标右键事件

contextMenu 事件的处理分为两部分:

  1. contextMenu 的展示
    1. image.png
  2. 右键项对应逻辑处理
    1. image.png

先实现contextMenu 的展示

  1. 创建 ContextMenu 组件,作为右键展示部分

先简单实现测试下:
image.png

const visible = ref(false)
/**
 * 展示 menu
 */
const openMenu = (e, index) => {
  visible.value = true
}

在router-link下进行基本的展示:
image.png
image.png
接下来实现:
1、绘制视图先不管位置,先处理视图部分
2、视图展示的位置 => 右键点击哪里就在哪里展示,而不是固定展示在一个位置上

1、contextMenu 的展示:

<template>
  <ul class="context-menu-container">
    <!-- 创建三个li,以及国际化 -->
    <li @click="onRefreshClick">
      {{ $t('msg.tagsView.refresh') }}
    </li>
    <li @click="onCloseRightClick">
      {{ $t('msg.tagsView.closeRight') }}
    </li>
    <li @click="onCloseOtherClick">
      {{ $t('msg.tagsView.closeOther') }}
    </li>
  </ul>
</template>

<script setup>
import { defineProps } from 'vue'
// 操作具体哪个tag,做标记,创建props
defineProps({
  index: {
    type: Number,
    required: true
  }
})

const onRefreshClick = () => {}

const onCloseRightClick = () => {}

const onCloseOtherClick = () => {}
</script>

<style lang="scss" scoped>
.context-menu-container {
  position: fixed;
  background: #fff;
  z-index: 3000;
  list-style-type: none;
  padding: 5px 0;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 400;
  color: #333;
  box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3);
  li {
    margin: 0;
    padding: 7px 16px;
    cursor: pointer;
    &:hover {
      background: #eee;
    }
  }
}
</style>

image.png
2、 在 tagsview 中控制 contextMenu 的展示
希望context的位置根据鼠标点击的位置移动。
鼠标右键的时候传递了event对象

<template>
  <div class="tags-view-container">
    <el-scrollbar class="tags-view-wrapper">
      <!-- contextmenu.prevent右击事件 -->
      <router-link
        class="tags-view-item"
        :class="isActive(tag) ? 'active' : ''"
        :style="{
          backgroundColor: isActive(tag) ? $store.getters.cssVar.menuBg : '',
          borderColor: isActive(tag) ? $store.getters.cssVar.menuBg : ''
        }"
        v-for="(tag, index) in $store.getters.tagsViewList"
        :key="tag.fullPath"
        :to="{ path: tag.fullPath }"
        @contextmenu.prevent="openMenu($event, index)"
      >
        {{ tag.title }}
        <svg-icon
          v-show="!isActive(tag)"
          icon="close"
          @click.prevent.stop="onCloseClick(index)"
        ></svg-icon>
      </router-link>
      </el-scrollbar>
    <context-menu
      v-show="visible"
      :style="menuStyle"
      :index="selectIndex"
      ></context-menu>
  </div>
</template>

<script setup>
  import ContextMenu from './ContextMenu.vue'
  import { ref, reactive, watch } from 'vue'
  import { useRoute } from 'vue-router'
  ...

  // contextMenu 相关
  const selectIndex = ref(0)
  const visible = ref(false)
  const menuStyle = reactive({
    left: 0,
    top: 0
  })
  /**
 * 展示 menu
 */
  const openMenu = (e, index) => {
    const { x, y } = e // 事件对象中,得到鼠标点击的位置
    // 作为行内样式绑定
    menuStyle.left = x + 'px'
    menuStyle.top = y + 'px'
    // 点击项
    selectIndex.value = index
    visible.value = true
  }
</script>

contextMenu 事件处理

对于 contextMenu 的事件一共分为三个:

  1. 刷新
  2. 关闭右侧
  3. 关闭所有

刷新 =>
router.go(n) 是 Vue Router 提供的一个方法,它可以在浏览器的历史记录中前进或后退 n 步。 当 n 为正数时,router.go(n) 会前进 n 步;当 n 为负数时,会后退 n 步;当 n0 时,它会重新加载当前的页面。在 如下 中,router.go(0) 相当于刷新当前页面。

const router = useRouter()
const onRefreshClick = () => {
  router.go(0)
}

store 中,创建删除 tagsmutations,该 mutations 需要同时具备以下三个能力:

  1. 删除 “右侧”
  2. 删除 “其他”
  3. 删除 “当前”
/**
   * 删除 tag
   * @param {type: 'other'||'right'||'index', index: index} payload
*/
removeTagsView(state, payload) {
    if (payload.type === 'index') { // 删除当前项
      state.tagsViewList.splice(payload.index, 1)
      return
    } else if (payload.type === 'other') { // 保留自己,删掉它之前和之后
      state.tagsViewList.splice(
        payload.index + 1,
        state.tagsViewList.length - payload.index + 1
      )  // 删除它之后的所有的
      state.tagsViewList.splice(0, payload.index) // 删除它之前的
    } else if (payload.type === 'right') {
      state.tagsViewList.splice(
        payload.index + 1,
        state.tagsViewList.length - payload.index + 1
      ) // 删除它之后的
    }
    setItem(TAGS_VIEW, state.tagsViewList) // 同步本地缓存(localStorage)
},

关闭右侧事件

const store = useStore()
const onCloseRightClick = () => {
  store.commit('app/removeTagsView', {
    type: 'right',
    index: props.index
  })
}

关闭其他

const onCloseOtherClick = () => {
  store.commit('app/removeTagsView', {
    type: 'other',
    index: props.index
  })
}

关闭当前(tagsview

/**
 * 关闭 tag 的点击事件
 */
const store = useStore()
const onCloseClick = index => {
  store.commit('app/removeTagsView', {
    type: 'index',
    index: index
  })
}

处理 contextMenu 的关闭行为

其实就改变它的visible,visible为true就为bdoy添加关闭菜单的事件。

/**
 * 关闭 menu
 */
const closeMenu = () => {
  visible.value = false
}

/**
 * 监听变化
 */
watch(visible, val => {
  if (val) {
    document.body.addEventListener('click', closeMenu)
  } else {
    document.body.removeEventListener('click', closeMenu)
  }
})

处理基于路由的动态过渡

处理基于路由的动态过渡  官方已经给出了示例代码,结合 router-viewtransition 我们可以非常方便的实现这个功能,除此之外再此基础上添加keep-alive。
image.png

<template>
  <div class="app-main">
    <!-- 利用v-slot 解构一些值,作用域插槽语法,它允许子组件将数据传递给父组件,父组件通过这个作用域插槽能够接收子组件传递的数据,并可以根据这些数据动态地渲染内容或进行其他逻辑处理 -->
    <!-- Component 是当前路由匹配的组件,route 是当前的路由对象,包含路径、参数、查询等信息。 -->
    <router-view v-slot="{ Component, route }">
      <!-- 利用transition 指定动画效果 -->
      <transition name="fade-transform" mode="out-in">
        <keep-alive>
          <!-- 动态组件,动态渲染Component -->
          <!-- :key="route.path" 用于强制 Vue 在路由变化时重新渲染组件。因为每个路径都是唯一的,所以 key 的变化会触发 Vue 重新创建组件实例,从而确保每个路由组件的独立性 -->
          <component :is="Component" :key="route.path" />
        </keep-alive>
      </transition>
    </router-view>
  </div>
</template>

动画

/* fade-transform */
/* 元素进入和离开视图时都会应用 */
.fade-transform-leave-active,
.fade-transform-enter-active {
  /* 表示元素的所有可动画属性在 0.5 秒内从初始状态过渡到最终状态。即:所有参与动画的属性(如 opacity 和 transform)都会在 0.5 秒内完成变化。 */
  transition: all 0.5s;
}

/* 进入过渡的初始状态 */
.fade-transform-enter-from {
  /* 一开始是完全透明 */
  opacity: 0;
  /* 一开始是从它本应的位置向左偏移了 30 像素 */
  transform: translateX(-30px); 
}

/* 离开过渡的结束状态 */
.fade-transform-leave-to {
  /*元素在离开时会变得完全透明 */
  opacity: 0;
  /*  元素在离开时会向右移动 30 像素 */
  transform: translateX(30px);
}

进入视图时:

  • 元素从 fade-transform-enter-from 状态开始,透明度为 0,向左偏移 30 像素。
  • 然后,在 0.5 秒内,元素的透明度逐渐增加到 1(完全可见),同时它从左边的位置平滑地移动到其正常位置。

离开视图时:

  • 元素开始时是正常位置和完全可见的状态。
  • fade-transform-leave-active 触发后,它在 0.5 秒内逐渐变得透明,同时向右移动 30 像素,直到完全消失。

应用场景

  • 这个动画效果通常用于在切换路由或显示/隐藏某个元素时,使得用户界面看起来更加流畅和动态。比如,当用户点击一个按钮切换页面内容时,当前页面内容会向右淡出,而新页面内容会从左边淡入,从而创建一种连贯的过渡效果。

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

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

相关文章

【SAM下游任务微调】TS-SAM: Fine-Tuning Segment-Anything Model for Downstream Tasks

TS-SAM: Fine-Tuning Segment-Anything Model for Downstream Tasks 论文链接&#xff1a;https://arxiv.org/pdf/2408.01835 代码链接&#xff1a;https://github.com/maoyangou147/TS-SAM 一、摘要 基于适配器的微调方法已经被研究用于改进SAM在下游任务上的性能。然而&am…

【2024】Datawhale X 李宏毅苹果书 AI夏令营 Task1

本文是关于李宏毅苹果书“第1章 机器学习基础”学习内容的记录。 1、术语解释 术语解释机器学习&#xff08;Machine Learning, ML&#xff09;机器学习是一种人工智能&#xff08;AI&#xff09;技术&#xff0c;它使计算机能够从数据中学习并做出决策或预测&#xff0c;而无…

【python计算机视觉编程——3.图像到图像的映射】

python计算机视觉编程——3.图像到图像的映射 3.图像到图像的映射3.1 单应性变换3.1.1 直接线性变换算法&#xff08;DLT&#xff09;3.1.2 仿射变换 3.2 图像扭曲3.2.1 图像中的图像3.2.2 分段仿射扭曲3.2.3 图像配准 3.3 创建全景图3.3.1 RANSAC3.3.2 稳健的单应性矩阵估计3.…

【二叉树】LC405-删除二叉搜索树的节点

文章目录 1 删除二叉树的节点思路其他代码参考 1 删除二叉树的节点 https://leetcode.cn/problems/delete-node-in-a-bst/description/ 给定一个二叉搜索树的根节点 root 和一个值 key&#xff0c;删除二叉搜索树中的 key 对应的节点&#xff0c;并保证二叉搜索树的性质不变。…

探索全球设计灵感:六大海外设计平台

海外设计网站对于设计师而言&#xff0c;不仅是灵感的源泉&#xff0c;更是专业成长的加速器。这些平台聚集了全球创意人士&#xff0c;提供了一个分享和发现最新设计趋势的环境。设计师可以通过这些网站学习行业内的创新技术&#xff0c;参与设计挑战&#xff0c;提升个人设计…

End-to-End视觉里程计新突破:从运动模糊图像中精确估计相机姿态

更多优质内容&#xff0c;请关注公众号&#xff1a;智驾机器人技术前线 1.论文信息 论文标题&#xff1a;MBRVO: A Blur Robust Visual Odometry Based on Motion Blurred Artifact Prior 作者&#xff1a;Jialu Zhang, Jituo Li*, Jiaqi Li, Yue Sun, Xinqi Liu, Zhi Zheng,…

饮水机复杂交互功能联网调试

饮水机复杂交互功能联网调试 引言 饮水机我们从最开始的放水和加热, 逐渐拓展到保温功能, 童锁功能, 红外检测功能, 对于这些复杂的交互功能, 我们如果通过按键进行调试, 会极大的增加我们的开发时间和成本, 如果我们频繁的进行烧录, 则如果涉及到一些中间变量, 则无法进行调试…

帆软BI怎么制作不等宽柱状图

帆软BI怎么制作不等宽柱状图 文章目录 帆软BI怎么制作不等宽柱状图不等宽柱状图起源一、怎么做不等宽柱状图准备二、操作步骤1.展示效果2.操作步骤-3.操作步骤 -图形属性4.操作步骤 -组件样式5.操作步骤 -横轴和纵轴6.完成7.不等宽柱状图与传统等宽柱状图对比 总结 不等宽柱状图…

【深度学习】嘿马深度学习笔记第5篇:神经网络与tf.keras,学习目标【附代码文档】

本教程的知识点为&#xff1a;深度学习介绍 1.1 深度学习与机器学习的区别 TensorFlow介绍 2.4 张量 2.4.1 张量(Tensor) 2.4.1.1 张量的类型 TensorFlow介绍 1.2 神经网络基础 1.2.1 Logistic回归 1.2.1.1 Logistic回归 TensorFlow介绍 总结 每日作业 神经网络与tf.keras 1.3 …

介绍云计算在医疗领域的应用实例

云计算在医疗领域的应用日益广泛&#xff0c;为医疗行业带来了诸多便利和创新。以下是几个典型的应用实例&#xff1a; 电子病历管理系统&#xff1a; 基于云计算技术的电子病历管理系统&#xff0c;通过互联网实现对病历数据的存储、管理、维护和查询等功能。这类系统能够自动…

关于助记词,词库的讨论

我有个想法&#xff0c;既然私钥碰撞的难度大。 -seed-&#xff08;pathmasterkey&#xff09;-privatekey-publickey-address 通过反推的难度大&#xff0c;那我可以尝试使用助记词碰撞 就例如&#xff0c;我生成1000个eth地址 1000个地址的助记词全部拿到&#xff0c;然后…

C++学习笔记——打印ASCII码

一、题目描述 二、代码 #include <iostream> using namespace std; int main() {char a_char;int a_int;cin >> a_char;a_int a_char;cout << a_int;return 0; }

【数据结构】关于TreeMap与TreeSet的使用你了解多少???

前言&#xff1a; &#x1f31f;&#x1f31f;本期讲解TreeMap与Set的相关知识&#xff0c;希望能帮到屏幕前的你。 &#x1f308;上期博客在这里&#xff1a;http://t.csdnimg.cn/K1moi &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 目录 &am…

开源模型应用落地-LangChain实用小技巧-使用各种Loader高效解析不同数据源(七)

一、前言 在 LangChain框架中&#xff0c;提供了Loader机制&#xff0c;以统一的方式来从各种数据源获取数据&#xff0c;使得开发人员可以方便地集成不同类型的数据源&#xff0c;而无需为每种数据源编写特定的加载代码。它可以将不同格式的数据转换为 LangChain 可以处理的统…

如何使用ssm实现新锐台球厅管理系统的设计与实现+vue

TOC ssm221新锐台球厅管理系统的设计与实现vue 系统概述 1.1 研究背景 如今互联网高速发展&#xff0c;网络遍布全球&#xff0c;通过互联网发布的消息能快而方便的传播到世界每个角落&#xff0c;并且互联网上能传播的信息也很广&#xff0c;比如文字、图片、声音、视频等…

Python(R)均方根误差平均绝对误差导图

&#x1f3af;要点 回归模型评估指标评估薪水预测模型评估员工倦怠率模型评估大气分析生成式对抗模型目标对象缺失下&#xff0c;性能估算法追踪模型误差指标降尺度大气学模拟模型准确性评估蛋白染色质相互作用模型评估 Python回归误差指标 平均绝对误差表示数据集中实际值和…

Manim实现目标的移动和出现速度控制

一&#xff0c;介绍 缓动函数 自定义参数随时间变化的速率。 现实生活中&#xff0c;物体并不是突然启动或者停止&#xff0c; 当然也不可能一直保持匀速移动。就像我们 打开抽屉的过程那样&#xff0c;刚开始拉的那一下动作很快&#xff0c; 但是当抽屉被拉出来之后我们会不自…

TCP协议中断开连接机制

目录 客户端与服务端四次挥手 关于TIME_WAIT状态 为什么TIME_WAIT状态等待的时间是2MSL&#xff1f; 客户端与服务端四次挥手 基于TCP协议通信的客户端与服务端断开连接就要进行四次挥手&#xff0c;如下图&#xff1a; 四次挥手过程中客户端与服务端状态转化&#xff1a; …

Rocm-Programming with HIP 内存分配

1. 主机内存&#xff08;Host Memory&#xff09; hipHostMalloc 是 HIP API 中的一个函数&#xff0c;它用于在主机上分配特殊的内存&#xff0c;这种内存被称为 "pinned" 或 "page-locked" 内存。这种内存有以下特点和用途&#xff1a; GPU 地址空间映射…

SD6201 同步增压DC/DC调节器芯片IC

一般描述 SD6201是高效率同步、PWM升压型DC/DC转换器&#xff0c;专为中型功率系统提供高效率解决方案而优化。该器件在0.9 V至4.4V的输入电压下工作&#xff0c;开关频率为1.4 MHz。这些功能允许使用微小、低剖面的电感和陶瓷电容器&#xff0c;从而最大限度地减少了整…