【Vue+ElementUI】Table表格实现自定义表头展示+表头拖拽排序(附源码)

效果图

在这里插入图片描述
在这里插入图片描述

因项目采用的是Vue2,所以这个功能目前采用的是Vue2的写法。
Vue3请自行修改扩展代码;或收藏关注帖子,后续Vue3项目如有用到会在本帖子更新修改。

安装vuedraggable(拖拽插件)

cnpm i vuedraggable

先说用法,下方附全源码

引入自定义表头组件

import indicatorTable from "@/components/indicatorTable/index.vue";

使用:(传参说明已在下方标识)

<indicatorTable
  ref="rois"
  :defaultArr="columns"
  :cardDataProp="cardDataProp"
  cacheKeyProp="keyROI"
  @propData="propsTableHander"
  currenKey="ROT"
/>

props参数说明:(均为必传字段)

// ref:用于调用子组件方法。
// columns:表头数据,例如:
[{
 prop: "cost_platform",
 label: "广告金",
}]

// cardDataProp:可选表头复选框,列如:
cardDataProp: [
  {
    title: "指标", // 每一项的分类title标题,详见第一张效果图
    checkboxes: [...columns], // columns这个就是上面的一样
  },
],

// cacheKeyProp:储存的key名,名字自定义来,避免缓存的key一样就行,列如:
cacheKeyProp="keyROI"

// propData:回调方法,用于更新表头,接受函数,直接表头columns数据 = 参数即可

// currenKey:保存的指标key,避免缓存的key一样就行。

页面table使用方法,需用循环:

<el-table
  v-loading="loading"
  :data="tableList"
  border
  @sort-change="tableSort"
  :height="tableHeight"
  ref="tableRef"
>
  <el-table-column
    v-for="item in columns"
    :prop="item.prop"
    :label="item.label"
    :width="item.width"
    align="center"
    sortable="custom"
    :show-overflow-tooltip="true"
  >
  </el-table-column>
</el-table>

上面表格的参数不用多说了吧,除非你不会前端!

附源码(拿来直接用!只要参数没问题!)

如遇到报错、不显示等问题,一定是参数不对!已自测 无任何报错或警告信息!
如需要Vue3版本,自行开发或私信,有空定会帮助!
新建组件直接复制:

<template>
  <div class="indicator-all-box">
    <el-popover placement="bottom" width="300" trigger="click">
      <div class="add-custom-indicator-container">
        <el-button type="primary" @click="addUserDefinedIndicators">
          新增自定义指标
        </el-button>
        <div class="indicator-list">
          <ul>
            <li
              v-for="(item, index) in pointerArr"
              :key="index"
              :class="currenPointIndex == index ? 'active-li' : ''"
              @click="pointClick(item, index)"
            >
              <div class="flex-indicator-item">
                <span>{{ item.title }}</span>
                <div class="right-indicator">
                  <i
                    class="el-icon-edit"
                    @click.stop.prevent="pointIndexHander(item, 'edit')"
                  ></i>
                  <i
                    class="el-icon-delete"
                    @click.stop.prevent="pointIndexHander(item, 'delete')"
                  ></i>
                </div>
              </div>
            </li>
          </ul>
        </div>
      </div>
      <el-button slot="reference" type="success">自定义指标</el-button>
    </el-popover>

    <!-- 弹窗自定义 -->
    <el-dialog :title="openTitle" :visible.sync="dialogVisible" width="70%">
      <div class="customize-indicator-data-container">
        <div class="card-checkbox-content-left">
          <el-card
            v-for="(item, index) in cardData"
            :key="index"
            class="box-card"
          >
            <div slot="header" class="clearfix">
              <span>{{ item.title }}</span>
              <el-checkbox
                v-model="item.selectedAll"
                @change="handleSelectAll(item)"
                :indeterminate="isIndeterminate(item)"
                style="float: right"
                >全选</el-checkbox
              >
            </div>
            <div class="check-card-item">
              <el-checkbox-group
                ref="checkboxGroup"
                v-model="selectedCheckboxes"
              >
                <el-checkbox
                  v-for="(checkbox, idx) in item.checkboxes"
                  :key="idx"
                  :label="checkbox.label"
                  >{{ checkbox.label }}</el-checkbox
                >
              </el-checkbox-group>
            </div>
          </el-card>
        </div>
        <div class="sort-view-dx">
          <el-divider>排序</el-divider>
          <div class="sort-row">
            <draggable
              v-if="selectedCheckboxes.length > 0"
              v-model="selectedCheckboxes"
              animation="300"
            >
              <p v-for="(item, index) in selectedCheckboxes" :key="index">
                {{ item }}
              </p>
            </draggable>
            <el-empty v-else></el-empty>
          </div>
        </div>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="addPointerSubmit">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import draggable from "vuedraggable";

export default {
  name: "indicatorTable",
  components: {
    draggable,
  },
  props: {
    // 默认指标
    defaultArr: {
      type: Array,
      required: true,
    },
    // 可选指标
    cardDataProp: {
      type: Array,
      required: true,
    },
    // 存储指标key
    cacheKeyProp: {
      type: String,
      required: true,
    },
    // 存储的索引key名
    currenKey: {
      type: String,
      required: true,
    },
  },
  data() {
    return {
      // 弹窗show
      dialogVisible: false,
      // 全部指标数组
      cardData: this.cardDataProp,
      // 勾选指标
      selectedCheckboxes: [],
      // 弹框title
      openTitle: "添加",
      // 下拉指标列表
      pointerArr: [],
      // 获取当前编辑item
      editItem: null,
      // 传出去的prop数组
      emitArr: null,
      // 当前选择的指标
      currenPointIndex: null,
    };
  },
  computed: {
    Local() {
      return {
        get(key) {
          const value = localStorage.getItem(key);
          if (value == "[]") {
            return null;
          } else {
            return value !== null ? JSON.parse(value) : null;
          }
        },
        set(key, value) {
          localStorage.setItem(key, JSON.stringify(value));
        },
        remove(key) {
          localStorage.removeItem(key);
        },
      };
    },
    // 指标指定label排序
    sortColumns() {
      return function (data, sort) {
        if (data) {
          return data.sort(
            (a, b) => sort.indexOf(a.label) - sort.indexOf(b.label)
          );
        }
      };
    },
    // 获取选指标label
    filterCheckbox() {
      return function (data, isSort = false, sortData) {
        if (data) {
          let filteredCheckboxes = [];
          this.cardData.forEach((item) => {
            item.checkboxes.forEach((checkbox) => {
              if (data.arrayCheck.includes(checkbox.label)) {
                filteredCheckboxes.push(checkbox);
              }
            });
          });
          // 获取后是否排序
          if (isSort) {
            return this.sortColumns(filteredCheckboxes, sortData);
          } else {
            return filteredCheckboxes;
          }
        }
      };
    },
  },
  created() {
    // this.Local.remove("displayType");
    this.getPointData("init");
  },
  methods: {
    // 存储key索引
    storeSetCurrentIndex(type = "set") {
      if (type === "set") {
        const getIndexObj = this.Local.get("pointIndex") || {};
        getIndexObj[this.currenKey] = this.currenPointIndex;
        this.Local.set("pointIndex", getIndexObj);
      } else {
        return this.Local.get("pointIndex") || {};
      }
    },
    // 选择当前指标
    pointClick(row, index) {
      if (this.currenPointIndex != index) {
        this.currenPointIndex = index;
        // 存储当前点击指标index
        this.storeSetCurrentIndex("set");
        const checkData = this.filterCheckbox(
          row,
          true,
          this.pointerArr[this.currenPointIndex].arrayCheck
        );
        this.$emit("propData", checkData);
      }
    },
    // 扩展方法-倍数ROI处理
    // roiDisposeFn() {
    //   const getPonit = this.Local.get(this.cacheKeyProp);
    //   const displayType = this.Local.get("displayType");
    //   const prointArrItem = this.pointerArr[this.currenPointIndex];
    //   const updatedArray = prointArrItem.arrayCheck.map((item) => {
    //     if (
    //       displayType == 2 &&
    //       item.startsWith("ROI") &&
    //       !item.includes("倍数")
    //     ) {
    //       return item + "倍数";
    //     } else if (displayType != 2 && item.includes("倍数")) {
    //       return item.replace("倍数", "");
    //     }
    //     return item;
    //   });
    //   const labelCheckBoxAll = this.filterCheckbox({
    //     arrayCheck: updatedArray,
    //   }).map((item) => item.label);
    //   if (prointArrItem.arrayCheck !== labelCheckBoxAll) {
    //     getPonit[this.currenPointIndex].arrayCheck = labelCheckBoxAll;
    //     this.Local.set(this.cacheKeyProp, getPonit);
    //     this.pointerArr[this.currenPointIndex].arrayCheck = labelCheckBoxAll;
    //   }
    // },
    // 获取-更新指标
    getPointData(type) {
      const getPonit = this.Local.get(this.cacheKeyProp);
      if (getPonit) {
        this.pointerArr = getPonit;
        this.currenIndexNob();
        const prointArrItem = this.pointerArr[this.currenPointIndex];
        this.roiDisposeFn();
        const checkData = this.filterCheckbox(
          this.pointerArr[this.currenPointIndex],
          true,
          prointArrItem.arrayCheck
        );
        if (checkData) {
          this.$emit("propData", checkData);
        }
      } else if (!getPonit && type !== "init") {
        // 如果是空
        this.Local.remove(this.cacheKeyProp);
        this.$emit("propData", []);
      } else {
        // 如果默认的
        if (this.defaultArr && type === "init" && this.pointerArr.length <= 0) {
          const arrs = JSON.parse(JSON.stringify(this.defaultArr));
          const labelsArray = arrs.map((item) => item.label);
          this.currenIndexNob();
          this.pointerArr.push({
            title: "默认指标",
            arrayCheck: labelsArray,
          });
          const prointArrItem = this.pointerArr[this.currenPointIndex];
          const checkData = this.filterCheckbox(
            prointArrItem,
            true,
            labelsArray
          );
          this.$emit("propData", checkData);
        }
      }
    },
    // 编辑-删除指标
    pointIndexHander(item, type) {
      if (type === "edit") {
        this.openTitle = "编辑";
        this.selectedCheckboxes = item.arrayCheck;
        this.editItem = item;
        this.dialogVisible = true;
      } else {
        const itemToDelete = this.pointerArr.find(
          (ls) => ls.title === item.title
        );
        if (itemToDelete) {
          const indexToDelete = this.pointerArr.indexOf(itemToDelete);
          if (indexToDelete > -1) {
            this.pointerArr.splice(indexToDelete, 1);
            this.Local.set(this.cacheKeyProp, this.pointerArr);
            // 删除当前行更新,否则不更新
            if (indexToDelete === this.currenPointIndex) {
              this.getPointData();
            } else {
              this.currenIndexNob();
            }
          }
        }
      }
    },
    // 全选当前指标
    handleSelectAll(item) {
      item.checkboxes.forEach((checkbox) => {
        const checkboxIndex = this.selectedCheckboxes.indexOf(checkbox.label);
        if (item.selectedAll && checkboxIndex === -1) {
          this.selectedCheckboxes.push(checkbox.label);
        } else if (!item.selectedAll && checkboxIndex !== -1) {
          this.selectedCheckboxes.splice(checkboxIndex, 1);
        }
      });
    },
    // 全选状态判断
    isIndeterminate(item) {
      const selectedLabels = this.selectedCheckboxes;
      const allLabels = item.checkboxes.map((checkbox) => checkbox.label);
      const selectedCount = selectedLabels.filter((label) =>
        allLabels.includes(label)
      ).length;
      item.selectedAll = selectedCount === allLabels.length;
      return selectedCount > 0 && selectedCount < allLabels.length;
    },
    // 指定索引
    currenIndexNob() {
      const getIndexObj = this.storeSetCurrentIndex("get");
      this.currenPointIndex = getIndexObj[this.currenKey];
      if (!this.currenPointIndex) {
        this.currenPointIndex = 0;
      } else {
        if (this.pointerArr.length <= 1) {
          this.currenPointIndex = 0;
        } else {
          this.currenPointIndex = getIndexObj[this.currenKey] || 0;
        }
      }
      this.storeSetCurrentIndex("set");
    },
    // 添加指标
    addPointerSubmit() {
      this.dialogVisible = false;
      this.emitArr = this.filterCheckbox(
        {
          arrayCheck: this.selectedCheckboxes,
        },
        true,
        this.selectedCheckboxes
      );
      const dataItem = {
        title: "",
        arrayCheck: this.selectedCheckboxes,
      };
      if (this.openTitle === "添加") {
        this.$prompt("请输入指标名", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          closeOnClickModal: false,
          inputValidator: (value) => {
            if (!value) {
              return "不能为空!";
            }
          },
          beforeClose: (action, instance, done) => {
            if (action === "confirm") {
              const isDuplicate = this.pointerArr.some(
                (item) => item.title === instance.inputValue
              );
              if (isDuplicate) {
                this.$message.error("已存在相同指标名");
                return false;
              } else {
                done();
              }
            } else {
              done();
            }
          },
        }).then(({ value }) => {
          dataItem.title = value;
          if (this.pointerArr && Array.isArray(this.pointerArr)) {
            const updatedData = [...this.pointerArr, dataItem];
            this.Local.set(this.cacheKeyProp, updatedData);
          } else {
            const newData = [dataItem];
            this.Local.set(this.cacheKeyProp, newData);
          }
          this.$emit("propData", this.emitArr);
          this.getPointData();
        });
      } else {
        const editIndex = this.pointerArr.findIndex(
          (item) => item.title === this.editItem.title
        );
        if (editIndex !== -1) {
          (dataItem.title = this.editItem.title),
            (this.pointerArr[editIndex] = dataItem);
          this.Local.set(this.cacheKeyProp, this.pointerArr);
        }
        this.$emit("propData", this.emitArr);
      }
    },
    // 新增自定义指标
    addUserDefinedIndicators() {
      this.openTitle = "添加";
      this.selectedCheckboxes = [];
      this.dialogVisible = true;
    },
  },
};
</script>

<style lang="scss" scoped>
.indicator-all-box {
  float: right;
  margin-right: 5px;
}
.indicator-list {
  ul {
    padding: 0;

    li {
      padding: 10px 0;
      border-bottom: 1px solid #e1e1e1;
    }
  }

  .flex-indicator-item {
    display: flex;
    justify-content: space-between;
    padding: 0 15px;

    .right-indicator {
      i {
        padding-left: 10px;
        display: inline-block;
        font-size: 16px;
        cursor: pointer;
      }
    }
  }
}

.box-card {
  margin-bottom: 10px;
}

.el-divider {
  margin: 10px 0;
}

.rihgt-all-check {
  float: right;
  padding: 3px 0;
}

.el-checkbox {
  margin-bottom: 10px;
}

.customize-indicator-data-container {
  display: flex;
  min-height: 60vh;

  .card-checkbox-content-left {
    max-height: 600px;
    overflow-y: scroll;
    flex: 1;
  }

  .sort-view-dx {
    width: 300px;
    margin-left: 15px;
    .sort-row {
      height: 60vh;
      overflow-y: scroll;
      p {
        background-color: #fdfdfd;
        height: 32px;
        line-height: 32px;
        border: 1px solid #ebebeb;
        padding: 0 10px;
        margin: 5px 0;

        &:hover {
          cursor: move;
        }
      }
    }
  }
}

.active-li {
  background-color: #efefef;
}
</style>

上方注释扩展方法说明:
比如你上方有筛选条件需要关联切换的,拿我自己的例子,见顶部ROI区域
他筛选条件有一个ROI、ROI倍数的筛选。然后字段展示是ROI123456…等,是循环的数量。切换ROI倍数的时候 表头原有的ROI需要变成ROI倍数 以及prop也一样要变化。
列如顶部ROI附加复选框的方法:
在这里插入图片描述

this.cardDataProp[1] = {
  title: "ROI指标",
  checkboxes: Array.from(
    { length: this.queryParams.displayNum },
    (_, i) => ({
      prop: `roi${i + 1}${
        this.queryParams.displayType == 1 ? "_rate" : ""
      }`,
      label: `ROI${i + 1}${
        this.queryParams.displayType == 2 ? "倍数" : ""
      }`,
    })
  ),
};

筛选条件选择切换displayType类型后调用 this.$refs.rois.getPointData("init"); 刷新表头

以上根据了选项displayType变化label和prop 但又是属于同一个label表头 只是字段不一样的 或者要用循环的,可采用这种方式,扩展方法自己研究…估计没有其他人需要用这个扩展的,就注释了,不用的可以删掉!

在这里插入图片描述
感谢你的阅读,如对你有帮助请收藏+关注!
只分享干货实战精品从不啰嗦!!!
如某处不对请留言评论,欢迎指正~
博主可收徒、常玩QQ飞车,可一起来玩玩鸭~

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

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

相关文章

github Commits must have verified signatures

1.首先确认是否有权限&#xff0c;如有权限的情况下那就是配置有问题了 我的情况是&#xff0c;能拉取代码&#xff0c;提交的时候出现这种情况&#xff1a;Commits must have verified signatures 这里是生成证书&#xff0c;如果已经生成过的&#xff0c;就不用生成了 ssh…

GIS之深度学习08:安装GPU环境下的pytorch

环境&#xff1a; cuda&#xff1a;12.1.1 cudnn&#xff1a;12.x pytorch&#xff1a;2.2.0 torchvision&#xff1a;0.17.0 Python&#xff1a;3.8 操作系统&#xff1a;win &#xff08;本文安装一半才发现pytorch与cuda未对应&#xff0c;重新安装了cuda后才开始的&a…

超声波清洗机哪个品牌好?四款热度高超声波清洗机力荐

在当今社会&#xff0c;随着生活节奏的加快&#xff0c;年轻人越来越多地依赖眼镜来纠正视力或保护眼睛。无论是为了时尚搭配&#xff0c;还是因为长时间面对电脑和手机屏幕导致的视力问题&#xff0c;眼镜已经成为许多年轻人日常生活中不可或缺的配件。然而&#xff0c;就在我…

SSH安全协议介绍

知识改变命运&#xff0c;技术就是要分享&#xff0c;有问题随时联系&#xff0c;免费答疑&#xff0c;欢迎联系&#xff01; SSH&#xff08;Secure Shell&#xff0c;安全外壳&#xff09;是一种网络安全协议&#xff0c;通过加密和认证机制实现安全的访问和文件传输等业…

植物病虫害:YOLO水稻虫害识别数据集(6类,五千余张图像,标注完整)

YOLO水稻虫害识别数据集&#xff0c;包含褐飞虱&#xff0c;绿叶蝉&#xff0c;正常叶片&#xff0c;稻虫&#xff0c;二化螟&#xff0c;蝇蛆6个类别&#xff0c;共五千余张图像&#xff0c;yolo标注完整。 适用于CV项目&#xff0c;毕设&#xff0c;科研&#xff0c;实验等 …

uniapp微信小程序获取当前位置

uni-app微信小程序uni.getLocation获取位置&#xff1b;authorize scope.userLocation需要在app.json中声明permission&#xff1b;小程序用户拒绝授权后重新授权-CSDN博客

AIOPS:Zabbix结合讯飞星火做自动化告警+邮件通知并基于人工智能提供解决方案

目前Zabbix官方已经提供Zabbix+ChatGPT的解决方案 ChatGPT一周年,你充分利用了吗?Zabbix+ChatGPT,轻松化解告警! 但是由于需要魔法等其他因素,比较不稳定,遂决定使用国内模型,这里我挑选的是讯飞星火,基于我之前的文档,在此基础上通过Zabbix的告警脚本实现调用AI模型…

安装及管理docker

文章目录 1.Docker介绍2.Docker安装3.免sudo设置4. 使用docker命令5.Images6.运行docker容器7. 管理docker容器8.创建image9.Push Image 1.Docker介绍 Docker 是一个简化在容器中管理应用程序进程的应用程序。容器让你在资源隔离的进程中运行你的应用程序。类似于虚拟机&#…

[LeetCode][102]二叉树的层序遍历——遍历结果中每一层明显区分

题目 102. 二叉树的层序遍历 给定二叉树的根节点 root&#xff0c;返回节点值的层序遍历结果。即逐层地&#xff0c;从左到右访问所有节点。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3],[9,20],[15,7]] 示例 2&#xff1a; 输入…

HDLBits刷题Day24,3.2.5.9 Design a Moore FSM

3.2.5.9 Design a Moore FSM 问题描述 分析&#xff1a; 1.s000时&#xff0c;打开fr1,fr2,fr3和补充水dfr 2.s001时&#xff0c;打开fr1,fr2 3.s011时&#xff0c;打开fr1 4.s111时&#xff0c;关闭 5.当水位下降时&#xff0c;打开dfr 绘制一下状态转移图 代码&#xff1a…

Qt Creator常见问题解决方法

Qt Creator源文件重命名的正确方法 光改文件名是不够的&#xff0c;还要在.pro文件中的SOURCES中把名字改成之后的。 中文乱码&#xff08;字符集设置&#xff09; 菜单栏-工具-选项-设置为utf-8

“Sora和Claude”大模型突起,普通人在AI人工智能赛道有哪些机遇?

文丨微三云营销总监胡佳东&#xff0c;点击上方“关注”&#xff0c;为你分享市场商业模式电商干货。 - 引言&#xff1a;去年时至今日百模大战&#xff0c;行业大模型一直是焦点的所在&#xff0c;简单来说就是“提供一个问题”或者“发布一个任务”他会根据你的指令&#x…

机器学习--循环神经网络(RNN)1

一、简介 循环神经网络&#xff08;Recurrent Neural Network&#xff09;是深度学习领域中一种非常经典的网络结构&#xff0c;在现实生活中有着广泛的应用。以槽填充&#xff08;slot filling&#xff09;为例&#xff0c;如下图所示&#xff0c;假设订票系统听到用户说&…

PyTorch基础(20)-- torch.gt() / torch.ge() / torch.le() / torch.lt()方法

一、前言 嗯……最近遇到的奇奇怪怪的方法很多了&#xff0c;学无止境啊&#xff01;学不完啊&#xff0c;根本学不完&#xff01;本篇文章介绍四个方法&#xff1a;torch.gt()、torch.ge()、torch.le()和torch.lt()方法&#xff0c;由于这四个方法很相似&#xff0c;所以放到…

【ebpf pwn】D^3CTF2022 -- d3bpf/d3bpf-v2

文章目录 前言d3bpfd3bpf-v2泄漏 map_addr泄漏 koffset任意地址读写 前言 题目链接 虽然 ebpf 的利用热潮已经过去&#xff0c;但是作为一个刚刚接触内核利用的菜鸡&#xff0c;还是觉得有必要学习学习 ebpf 相关的漏洞利用&#xff0c;当然笔者不会在此花费太多时间&#xf…

CLion中常用快捷键(仍适用其他编译软件)

基本编辑操作&#xff1a; 复制&#xff1a;Ctrl C粘贴&#xff1a;Ctrl V剪切&#xff1a;Ctrl X撤销&#xff1a;Ctrl Z重做&#xff1a;Ctrl Shift Z &#xff08;不小心撤销了 需要返回之前的操作 相当于下一步&#xff09;全选&#xff1a;Ctrl A 导航&#xff1…

day18_支付宝支付项目部署(保存支付信息,支付接口,支付宝异步回调)

文章目录 1 支付1.1 需求说明1.2 支付宝支付1.2.1 产品介绍产品特色使用示例申请条件费率 1.2.2 接入准备1.2.3 手机网站支付快速接入1.2.4 官方demo研究 1.3 环境搭建(service-pay)1.4 后端接口1.4.1 保存支付信息实现流程说明查询订单接口开发openFeign接口定义代码实现添加依…

【重温设计模式】备忘录模式及其Java示例

备忘录模式的概述 在软件设计的世界中&#xff0c;备忘录模式是一种行为设计模式&#xff0c;它的主要作用是保存对象的当前状态&#xff0c;以便在将来的某个时间点&#xff0c;可以将对象恢复到这个保存的状态。这种模式的命名源于生活中的备忘录&#xff0c;我们常常用它来…

P1914 小书童——凯撒密码

题目描述&#xff1a; AC代码&#xff1a; #include<iostream> #include<cstring>using namespace std;int main() {int n;scanf("%d",&n);string str;cin >> str;//字符串密码输入 for(int i0;i<str.size();i) //遍历字符串中的字符使其…

Unity的PICO项目基础环境搭建笔记(调试与构建应用篇)

文章目录 前言一、为设备开启开发者模式1、开启PICO VR一体机。前往设置>通用>关于本机>软件版本号2、一直点击 软件版本号 &#xff0c;直到出现 开发者 选项3、进入 开发者模式&#xff0c;打开 USB调试&#xff0c;选择 文件传输 二、实时预览应用场景1、下载PC端的…