vue3 table 按住鼠标左键范围框选v2(选择逻辑优化,框选有值颜色不变,清空框选样式不变)

news2024/12/29 10:29:51

 



<template>
  {{ tabaleData }}
    <Params />
    <el-row>
        <el-col :span="6"><el-button type="primary" @click="loadData">导入样本表</el-button></el-col>
        <el-col :span="2"><el-button type="c1" @click="changeData('#90d999')">标定空位</el-button></el-col>
        <el-col :span="3"><el-button type="c2" @click="changeData('#8db8f3')">qPCR定量</el-button></el-col>
        <el-col :span="2"><el-button type="c3">微量样本</el-button></el-col>
        <el-col :span="2"><el-button type="c4">常量样本</el-button></el-col>
        <el-col :span="2"><el-button type="c5">阴性对照</el-button></el-col>
        <el-col :span="2"><el-button type="c6">阳性对照</el-button></el-col>
        <el-col :span="2"><el-button type="c7">直扩样本</el-button></el-col>
        <el-col :span="2"><el-button type="c8">梯度样本</el-button></el-col>
    </el-row>
    <el-divider />
    <Cab ref="cab" :tabaleData="tabaleData"   @update:tabaleData="tabaleData = $event" :test="test"   @update:test="test = $event" :colNum="colNum" :rowNum="rowNum"/>
    <el-row style="height: 10px;"/>
    <ElRow :gutter="20" justify="space-between" >
    <ElCol  v-for="item in testTypes" :key="item.ItemID" :xl="6" :lg="6" :md="12" :sm="12" :xs="24">
      <ElCard shadow="hover" class="mb-20px hand" >
        <ElSkeleton :loading="loading" animated :rows="2">
          <template #default>
            <div :class="` flex justify-between`">
              <div class="flex flex-col">
                <div :class="` text-26px  text-gray-700 text-right`">{{ item.ItemCode }}</div>
              </div>
            </div>
          </template>
        </ElSkeleton>
      </ElCard>
    </ElCol>
  </ElRow>

</template>

<script setup lang="ts">
import  Params from './components/Params.vue'
import TableSel from  './components/TableSel.vue'   
import Cab from  './components/Cab.vue' 
import { CountTo } from '@/components/CountTo'
import { useDesign } from '@/hooks/web/useDesign'
import { useI18n } from '@/hooks/web/useI18n'
import { ref, reactive } from 'vue'
import { getCountApi } from '@/api/dashboard/analysis'
import type { AnalysisTotalTypes } from '@/api/dashboard/analysis/types'
import { sampleItemList } from '@/api/bokun/b1'
import { ElRow, ElCol, ElCard, ElSkeleton } from 'element-plus'
const { t } = useI18n()


const tabaleData = ref<any>([])

const colNum = ref(7)
const rowNum = ref(7)

const getCellId  = (rindex,cindex) =>{
  return (cindex ) * colNum.value + (rindex )
}

//填充数据横纵
const addCell = () => {
  // let colNum = 7
  // let rowNum = 7
  let dataArr =<any> []

  console.log('rowNum ',rowNum)
  const myRow = 1
  const myCol = 2
  for (let i = 0; i <myCol; i++) {
    for (let j = 0; j <myRow; j++) {
      const obj =  { name: '小明',bcolor: '#ab9996', type: '0' ,x:i,y:j }
      dataArr.push(obj)
    }
  }
  let tabaleDataTemp =<any> []
  for (let i = 0; i <dataArr.length; i++) {
    const obj = dataArr[i]
    const cellId  =getCellId (obj.x,obj.y)
    obj['id'] = cellId
    tabaleDataTemp.push(obj)

  }
  tabaleData.value = tabaleDataTemp
  console.log('tabaleData ', tabaleData)
}


addCell()






const loading = ref(true)
const oo = '名'
let ss = ref(oo)
let test = ref('123')
const cab = ref()


const changeData = (color) =>{
  cab.value.changeData(color)
}



let testTypes=ref<any[]>([])

const getSampleItemList = async () => {
 
  const res = await sampleItemList()
    .catch(() => {})
    .finally(() => {
      loading.value = false
    })
  if (res) {
    ss.value = "往往"
    testTypes.value = [...res]
    console.log("后台请求实验类型的结果:",ss.value)
  }
}
getSampleItemList()




</script>

<style lang="less" scoped>

@c1:#b4cade;
@c2:#dcb2b0;
@c3:#90d999;
@c4:#8db8f3;
@c5:#bb98d4;
@c6:#eb8596;
@c7:#f49c08;
@c8:#efdbdb;
@font-s:
// color1
.el-button--c1.is-active,
.el-button--c1:active {
  background: @c1;
  border-color: @c1;
  font-weight: bold;
  color: #000000;
}
 
.el-button--c1:focus,
.el-button--c1:hover {
  background: @c1;
  border-color: @c1;
  font-weight: bold;
  color: #000000;
}
 
.el-button--c1 {
  background-color: @c1;
  border-color: @c1;
  font-weight: bold;
  color: #000000;
}
// color2
.el-button--c2.is-active,
.el-button--c2:active {
  background: @c2;
  border-color: @c2;
   font-weight: bold;
  color: #000000;
}
 
.el-button--c2:focus,
.el-button--c2:hover {
  background: @c2;
  border-color: @c2;
  font-weight: bold;
  color: #000000;
}
 
.el-button--c2 {
  background-color: @c2;
  border-color: @c2;
  font-weight: bold;
  color: #000000;
}
// color2
.el-button--c2.is-active,
.el-button--c2:active {
  background: @c2;
  border-color: @c2;
  font-weight: bold;
  color: #000000;
}
 
.el-button--c2:focus,
.el-button--c2:hover {
  background: @c2;
  border-color: @c2;
  font-weight: bold;
  color: #000000;
}
 
.el-button--c2 {
  background-color: @c2;
  border-color: @c2;
  font-weight: bold;
  color: #000000;
}

// color3
.el-button--c3.is-active,
.el-button--c3:active {
  background: @c3;
  border-color: @c3;
  font-weight: bold;
  color: #000000;
}
 
.el-button--c3:focus,
.el-button--c3:hover {
  background: @c3;
  border-color: @c3;
  font-weight: bold;
  color: #000000;
}
 
.el-button--c3 {
  background-color: @c3;
  border-color: @c3;
  font-weight: bold;
  color: #000000;
}

// color4
.el-button--c4.is-active,
.el-button--c4:active {
  background: @c4;
  border-color: @c4;
  font-weight: bold;
  color: #000000;
}
 
.el-button--c4:focus,
.el-button--c4:hover {
  background: @c4;
  border-color: @c4;
  font-weight: bold;
  color: #000000;
}
 
.el-button--c4 {
  background-color: @c4;
  border-color: @c4;
  font-weight: bold;
  color: #000000;
}
// color5
.el-button--c5.is-active,
.el-button--c5:active {
  background: @c5;
  border-color: @c5;
  font-weight: bold;
  color: #000000;
}
 
.el-button--c5:focus,
.el-button--c5:hover {
  background: @c5;
  border-color: @c5;
  font-weight: bold;
  color: #000000;
}
 
.el-button--c5 {
  background-color: @c5;
  border-color: @c5;
  font-weight: bold;
  color: #000000;
}

// c6
.el-button--c6.is-active,
.el-button--c6:active {
  background: @c6;
  border-color: @c6;
  font-weight: bold;
  color: #000000;
}
 
.el-button--c6:focus,
.el-button--c6:hover {
  background: @c6;
  border-color: @c6;
  font-weight: bold;
  color: #000000;
}
 
.el-button--c6 {
  background-color: @c6;
  border-color: @c6;
  font-weight: bold;
  color: #000000;
}

// c7
.el-button--c7.is-active,
.el-button--c7:active {
  background: @c7;
  border-color: @c7;
  font-weight: bold;
  color: #000000;
}
 
.el-button--c7:focus,
.el-button--c7:hover {
  background: @c7;
  border-color: @c7;
  font-weight: bold;
  color: #000000;
}
 
.el-button--c7 {
  background-color: @c7;
  border-color: @c7;
  font-weight: bold;
  color: #000000;
}

// c8
.el-button--c8.is-active,
.el-button--c8:active {
  background: @c8;
  border-color: @c8;
  font-weight: bold;
  color: #000000;
}
 
.el-button--c8:focus,
.el-button--c8:hover {
  background: @c8;
  border-color: @c8;
  font-weight: bold;
  color: #000000;
}
 
.el-button--c8 {
  background-color: @c8;
  border-color: @c8;
  font-weight: bold;
  color: #000000;
}

.hand{
  background-color: #afd4e6;
  cursor: pointer;
  -webkit-user-select: none; /* Chrome/Safari/Opera */
  -moz-user-select: none; /* Firefox */
  -ms-user-select: none; /* Internet Explorer/Edge */
  user-select: none; /* Non-prefixed version, currently not supported by any browser */
}



</style>

 

<template>
  
  {{ colNum }}
  {{ rowNum }}
  <table
    border="1"
    id="cabinet_latte_table"
    align="center"
    cellpadding="10"
    cellspacing="0"
  >

  <tr  v-for="rindex of rowNum" :key="rindex" :id="rindex" style="height: 30px;" >
      <td
        :id="getCellId(rindex,cindex)"
        :initRow="rindex"
        :initCol="cindex"
        :type = "getObject(rindex,cindex).type"
        :col="JSON.stringify(getObject(rindex,cindex))"
        :myData="col"
        @mousedown="handleMouseDown"
        @mouseup="handleMouseUp"
        @contextmenu="openContextMenu($event)"
        v-for="cindex of colNum" :key="cindex"
        :style="{width:widthp,height:heightp,backgroundColor:getObject(rindex,cindex).bcolor}"
        class="cell"
      >
        {{getCellId(rindex,cindex) }} {{getObject(rindex,cindex) }}
      </td>
    </tr>

    <!-- <tr v-for="(row, rindex) in tabaleData" :key="row.id" :id="rindex" style="height: 30px;" >


      <td
        :id="col.id"
        :initRow="rindex"
        :initCol="cindex"
        :col="JSON.stringify(col)"
        :myData="col"
        @mousedown="handleMouseDown"
        @mouseup="handleMouseUp"
        @contextmenu="openContextMenu($event)"
        v-for="(col, cindex) in row"
        :key="col.id"
        :style="{width:widthp,height:heightp,backgroundColor:getBackgroundColor(col.bcolor)}"
        class="cell"
      >
        {{ col.name }}-{{ col.id }}-{{ cindex }}-{{ rindex }}-{{ col.bcolor }}
      </td>
    </tr> -->
  </table>
</template>
<script setup>
import guid from '@/utils/generator'
import { reactive, ref, nextTick, defineProps,defineEmits  } from 'vue'


// 定义props
const props = defineProps({

  whStyle:{
    type: [Array, Object],
    default: () => {
      return { width: '50px', height: '40px' ,backgroundColor : '#eb8596'}
    }
  },
  test:{
    type: String,
    default:''

  },
  colNum:{
    type: Number,
    default:''

  },
  rowNum:{
    type: Number,
    default:''

  },
  widthp:{
    type: String,
    default:'50px'

  },
  heightp:{
    type: String,
    default:'50px'
  },
  tabaleData:{
    type: [Array],
    default: () => {
      return []
    }
  }
});

const { tabaleData,colNum,rowNum } = props;
let emit=defineEmits(["update:tabaleData","update:test"]);//自定义的更新num事件
const changeData = (color)=>{
  
  for(let i=0;i<chooseCellsArea.length;i++){
    const chooseCell = chooseCellsArea[i]
   // console.log('chooseCell ',chooseCell)
    const id = chooseCell.getAttribute('id')
    console.log('chooseCell id',id)
    const findCell = tabaleData.find(item => item.id ==  id)
    if(findCell){
      console.log('找到一个 tabaleData : findCell ')
      findCell.bcolor = color
    }
   
  }
  emit("update:tabaleData",tabaleData);
  emit("update:test",color);
}




const getCellId  = (rindex,cindex) =>{
  return (cindex - 1) * colNum + (rindex - 1)
}

const getObject = (rindex,cindex) =>{
  const pDataVarName = getCellId(rindex,cindex)
  if (tabaleData != null && tabaleData[pDataVarName]) {
      return tabaleData[pDataVarName]
    } else {
      return { name: '小li', type: '-1'}
    }
}



const dragging = ref(false)
const tableId = 'cabinet_latte_table'
const contextMenuTool = ref()
let chooseCellsArea = reactive([])
let startCell = ref({})
let endCell = ref({})


const openContextMenu = (event) => {
  contextMenuTool.value.openContextMenu(event)
}

const isOkRang = (initRow, initCol, startRow, startCol, endRow, endCol) => {
  return initRow >= startRow && initRow <= endRow && initCol >= startCol && initCol <= endCol
  //  ||(initRow >= endRow && initRow <= startRow && initCol >= endCol && initCol <= startCol)
}

// 获取范围并且将改变边框颜色
const applyBorderStyles = (tableId, startRow, startCol, endRow, endCol) => {
  clearBorderStyles(tableId)
  const cellList = document.getElementById(tableId).querySelectorAll('td')

  //   let endRowNum = endRow;
  //   let endColNum = endCol;
  const cellsInRange = []
  const cellsIdsRange = []
  cellList.forEach((cell) => {
    //遍历所有的td,在那个开始和当前停留位置的td的范围内的都设置选中样式 huang
    const initRow = parseInt(cell.getAttribute('initrow'), 10)
    const initCol = parseInt(cell.getAttribute('initcol'), 10)
    // 判断单元格是否在指定范围内
    // if (initRow >= startRow && initRow <= endRow && initCol >= startCol && initCol <= endCol) {
    if (isOkRang(initRow, initCol, startRow, startCol, endRow, endCol)) {
      // console.log('我看真正添加的 initRow ',initRow)
      // console.log('我看真正添加的 initCol ',initCol)
      cellsInRange.push(cell)

      chooseCellsArea = cellsInRange

      
      const type =cell.getAttribute('type')
      if(type=='-1'){
        cell.style.backgroundColor = '#c0bfbf'
      }




      // 应用顶部边框样式
      if (initRow === startRow) {
        cell.style.borderTop = '2px solid #409eff'
      }

      // 应用底部边框样式
      if (initRow === endRow) {
        cell.style.borderBottom = '2px solid #409eff'
      }

      // 应用左侧边框样式
      if (initCol === startCol) {
        cell.style.borderLeft = '2px solid #409eff'
      }

      // 应用右侧边框样式
      if (initCol === endCol) {
        cell.style.borderRight = '2px solid #409eff'
      }
    }
  })
  //console.log('选中的单元格', chooseCellsArea)
}

const clearBorderStyles = (tableId) => {
  const rowList = document.getElementById(tableId).querySelectorAll('tr')
  if (!rowList) return

  // 遍历所有行和单元格,清除边框样式
  for (const row of rowList) {
    for (const cell of row.cells) {
      cell.style.borderTop = ''
      cell.style.borderBottom = ''
      cell.style.borderLeft = ''
      cell.style.borderRight = ''
      const type =cell.getAttribute('type')
      if(type=='-1'){
        cell.style.backgroundColor = 'transparent'
      }
     
    }
  }
}
const handleMouseDown = (event) => {
  nextTick(() => {
    if (event.button === 0) {
      dragging.value = true

      // 获取起始单元格信息,这里可能需要一些逻辑来确定单元格的行和列
      const target = event.currentTarget
      if (target) {
        console.log('摁下initrow.value ', target.attributes.initrow.value)
        console.log('摁下initcol.value ', target.attributes.initcol.value)
        const row = Number(target.attributes.initrow.value)
        const col = Number(target.attributes.initcol.value)
        const cellId = target.id
        //记录左键点击开始位置 huang
        startCell.value = { cellId, row, col }
        console.log('按完了 加里没有', startCell.value)
      }

      // 添加全局鼠标移动事件监听
      window.addEventListener('mousemove', handleMouseMove)
    }
  })
}
const handleMouseUp = (event) => {
  dragging.value = false

  // 移除全局鼠标移动事件监听
  window.removeEventListener('mousemove', handleMouseMove)
}

const handleMouseMove = (event) => {
  //   if (!this.dragging) {
  //     return;
  //   }
  //   console.log('的高亮显示');
  // 这里可以根据需要添加逻辑,例如更新当前单元格的高亮显示
  nextTick(() => {})
  if (event.button === 0) {
    //当前鼠标位置的组件
    const { target } = event
    // console.log('target.parentNode', event);
    if (target) {
      //当前鼠标位置的行数 huang
      const row = Number(target.attributes.initrow.value)
      //当前鼠标位置的列数 huang
      const col = Number(target.attributes.initcol.value)

      clearBorderStyles(tableId)
      applyBorderStyles(tableId, startCell.value.row, startCell.value.col, row, col, target.id)
    }
  }
}

defineExpose({
  changeData,
})
</script>

<style lang="scss" scoped>
table {
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
  -khtml-user-selece: none;
  /*上面都是兼容性问题,具体看浏览器版本或什么浏览器*/
  user-select: none;
}
.cell {
  padding: 5px;
  font-size: 15px;
}
</style>

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

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

相关文章

Qt for android 获取USB设备列表(一)Java方式 获取

简介 QtActivity 作为 Qt 应用程序的入口点&#xff0c;负责启动和配置 Qt 应用程序的信息&#xff0c; 后面我们继承 QtActivity 做自定义控制&#xff0c;了解一下 Activity 生命周期概念&#xff0c; 因为 QtActivity 继承自Android的activity&#xff0c;使用周期函数完成我…

YOLOv10详细解读 | 一文带你深入了解yolov10的创新点(附网络结构图 + 举例说明)

前言 Hello大家好&#xff0c;我是Snu77&#xff0c;继YOLOv9发布时间没有多久&#xff0c;YOLOv10就紧接着发布于2024.5.23号&#xff08;不得不感叹YOLO系列的发展速度&#xff0c;但要纠正大家的观点就是不是最新的就一定最好&#xff09;&#xff01; 本文给大家带来的是…

Memcached 应该如何使用?

在【宝塔下应该用 Memcached 还是 Redis&#xff1f;】一文里&#xff0c;明月已经说过对于我们网站服务器来说 Memcached 才是首选&#xff0c;因为 Redis 虽然跟 Memcached 类似但更偏向于集群服务器&#xff0c;对于我们普通的站点服务器来说&#xff0c;也就是用了 Redis 大…

基于 BERT 对 IMDB 电影评论进行情感分类

前言 系列专栏:【深度学习:算法项目实战】✨︎ 涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域,讨论了各种复杂的深度神经网络思想,如卷积神经网络、循环神经网络、生成对抗网络、门控循环单元、长短期记…

Tomcat部署项目的方式

目录 1、Tomcat发布项目的方式 方式1&#xff1a; 直接把项目发布到webapps目录下 方式2&#xff1a;项目发布到ROOT目录 方式3&#xff1a;虚拟路径方式发布项目 方式4&#xff1a;(推荐)虚拟路径&#xff0c;另外的方式&#xff01; 方式5&#xff1a;发布多个网站 1、…

用户态下屏蔽全局消息钩子 —— ClientLoadLibrary 指针覆盖

目录 前言 一、研究 SetWindowsHookEx 的机制 二、概念验证 三、运行效果分析 四、总结与展望 参考文献 原文出处链接&#xff1a;[https://blog.csdn.net/qq_59075481/article/details/139206017] 前言 SetWindowsHookEx 函数帮助其他人员注入模块到我们的进程&#x…

Java后端开发一年经验,跳槽如何准备?

跳槽是一项重要的决定&#xff0c;需要慎重考虑并做好充分的准备。我这里有一套编程入门教程&#xff0c;不仅包含了详细的视频讲解&#xff0c;项目实战。如果你渴望学习编程&#xff0c;不妨点个关注&#xff0c;给个评论222&#xff0c;私信22&#xff0c;我在后台发给你。 …

SpringCloud(3)-OpenFeign相关配置

OpenFeign 是个声明式 WebService 客户端&#xff0c;使用 OpenFeign 让编写 Web Service 客户端更简单。Spring Cloud 对 OpenFeign 进 行 了 封 装 使 其 支 持 了 Spring MVC 标 准 注 解 和 HttpMessageConverters。OpenFeign 可以与 Eureka 和 Ribbon 组合使用以支持负载均…

Tensorflow2.0笔记 - AutoEncoder做FashionMnist数据集训练

本笔记记录自编码器做FashionMnist数据集训练&#xff0c;关于autoencoder的原理&#xff0c;请自行百度。 import os import time import tensorflow as tf from tensorflow import keras from tensorflow.keras import datasets, layers, optimizers, Sequential, metrics, …

17.7K星开源产品分析平台:Posthog

Posthog&#xff1a;开源洞察&#xff0c;产品优化的得力助手 - 精选真开源&#xff0c;释放新价值。 概览 PostHog是一个全面开源的平台&#xff0c;旨在帮助团队构建更好的产品。它提供了从产品分析到会话回放、功能标志和A/B测试等一系列工具&#xff0c;支持自托管&#x…

Keras深度学习框架第二十讲:使用KerasCV中的Stable Diffusion进行高性能图像生成

1、绪论 1.1 概念 为便于后文讨论&#xff0c;首先进行相关概念的陈述。 Stable Diffusion&#xff1a;Stable Diffusion 是一个在图像生成领域广泛使用的技术&#xff0c;尤其是用于文本到图像的转换。它基于扩散模型&#xff08;Diffusion Models&#xff09;&#xff0c;这…

Springboot017学生读书笔记共享

springboot005学生心理咨询评估系统 亲测完美运行带论文&#xff1a;获取源码&#xff0c;私信评论或者v:niliuapp 运行视频 Springboot017学生读书笔记共享 包含的文件列表&#xff08;含论文&#xff09; 数据库脚本&#xff1a;db.sql其他文件&#xff1a;ppt.ppt论文&am…

Java+Swing+Mysql实现飞机订票系统

一、系统介绍 1.开发环境 操作系统&#xff1a;Win10 开发工具 &#xff1a;Eclipse2021 JDK版本&#xff1a;jdk1.8 数据库&#xff1a;Mysql8.0 2.技术选型 JavaSwingMysql 3.功能模块 4.数据库设计 1.用户表&#xff08;users&#xff09; 字段名称 类型 记录内容…

【Linux】Linux的安装

文章目录 一、Linux环境的安装虚拟机 镜像文件云服务器&#xff08;可能需要花钱&#xff09; 未完待续 一、Linux环境的安装 我们往后的学习用的Linux版本为——CentOs 7 &#xff0c;使用 Ubuntu 也可以 。这里提供几个安装方法&#xff1a; 电脑安装双系统&#xff08;不…

OpenWrt 安装Quagga 支持ospf Bgp等动态路由协议 软路由实测 系列四

1 Quagga 是一个路由软件套件, 提供 OSPFv2,OSPFv3,RIP v1 和 v2,RIPng 和 BGP-4 的实现. 2 web 登录安装 #或者ssh登录安装 opkg install quagga quagga-zebra quagga-bgpd quagga-watchquagga quagga-vtysh # reboot 3 ssh 登录 #重启服务 /etc/init.d/quagga restart #…

Linux下Vision Mamba环境配置+多CUDA版本切换

上篇文章大致讲了下Vision Mamba的相关知识&#xff0c;网上关于Vision Mamba的配置博客太多&#xff0c;笔者主要用来整合下。 笔者在Win10和Linux下分别尝试配置相关环境。 Win10下配置 失败 \textcolor{red}{失败} 失败&#xff0c;最后出现的问题如下&#xff1a; https://…

ps进程查看命令详解

1、PS 命令是什么 查看它的man手册可以看到&#xff0c;ps命令能够给出当前系统中进程的快照。它能捕获系统在某一事件的进程状态。如果你想不断更新查看的这个状态&#xff0c;可以使用top命令。 2、ps命令支持三种使用的语法格式 UNIX 风格&#xff0c;选项可以组合在一起…

flutter 实现旋转星球

先看效果 planet_widget.dart import dart:math; import package:flutter/material.dart; import package:vector_math/vector_math_64.dart show Vector3; import package:flutter/gestures.dart; import package:flutter/physics.dart;class PlanetWidget extends StatefulW…

Android14 - 绘制系统 - 概览

从Android 12开始&#xff0c;Android的绘制系统有结构性变化&#xff0c; 在绘制的生产消费者模式中&#xff0c;新增BLASTBufferQueue&#xff0c;客户端进程自行进行queue的生产和消费&#xff0c;随后通过Transation提交到SurfaceFlinger&#xff0c;如此可以使得各进程将缓…