【sgTransfer】自定义组件:带有翻页、页码、分页器的穿梭框组件,支持大批量数据的穿梭显示。

 

特性: 

  1. 表格宽度可以自定义
  2. 翻页器显示控件可以自定义
  3. 列配置项可以设置显示字段列名称、宽度、字段名
  4. 可以配置搜索框提示文本,支持搜索过滤
  5. 穿梭框顶部标题可以自定义
  6. 左右箭头按钮文本可以设置

sgTransfer源码

<template>
    <div :class="$options.name">
        <div class="sg-start " :style="{ width: width }">
            <div class="sg-title" v-if="titles">
                {{ titles[0] }}
            </div>
            <div class="sg-search">
                <el-input style="width: 100%;" v-model.trim="inputSearchValue_start" maxlength="20" :show-word-limit="false"
                    :placeholder="filterPlaceholder || `请输入搜索内容...`" clearable @keyup.native.enter="initListStart"
                    @clear="initListStart">
                    <el-button slot="append" icon="el-icon-search" @click="initListStart" />
                </el-input>
            </div>
            <div class="sg-table">
                <el-table ref="table_start" :data="tableData_start" :header-cell-style="{ background: '#f5f7fa' }"
                    :height="'300px'" style="width: 100%" stripe @selection-change="selection_start_change"
                    :row-class-name="row_class_name" @row-click="row_click_start">
                    <el-table-column type="selection" minWidth="50" :selectable="selectable" />
                    <el-table-column v-for="(a, i) in tableItems_start" :key="i" :prop="a.prop" :label="a.label"
                        :width="a.width || false" :minWidth="a.minWidth || false" show-overflow-tooltip />
                </el-table>
            </div>
            <div class="sg-pagination">
                <el-pagination background :hidden="startPage.total <= 10" :layout="layout" :page-sizes="[10, 20, 50]"
                    :pager-count="5" :current-page.sync="startPage.currentPage" :page-size.sync="startPage.pageSize"
                    :total="startPage.total" @size-change="pageChange" @current-change="pageChange" />
            </div>
        </div>
        <div class="sg-center ">
            <el-button :disabled="disabledLeftButton" @click="remove" type="primary" icon="el-icon-arrow-left">{{
                buttonTexts ? buttonTexts[0] : ''
            }}</el-button>
            <el-button :disabled="disabledRightButton" @click="add" type="primary">{{ buttonTexts ? buttonTexts[1] : '' }}<i
                    class="el-icon-arrow-right" style="margin-left: 5px;"></i></el-button>

        </div>
        <div class="sg-end " :style="{ width: width }">
            <div class="sg-title" v-if="titles">
                {{ titles[1] }}
            </div>
            <div class="sg-search">
                <el-input style="width: 100%;" v-model.trim="inputSearchValue_end" maxlength="20" :show-word-limit="false"
                    :placeholder="filterPlaceholder || `请输入搜索内容...`" clearable
                    @keyup.native.enter="initListEnd({ currentPage: 1 })" @clear="initListEnd">
                    <el-button slot="append" icon="el-icon-search" @click="initListEnd({ currentPage: 1 })" />
                </el-input>
            </div>
            <div class="sg-table">
                <el-table ref="table_end" :data="tableData_end" :header-cell-style="{ background: '#f5f7fa' }"
                    :height="'300px'" style="width: 100%" stripe @selection-change="selection_end_change"
                    @row-click="row_click_end">
                    <el-table-column type="selection" minWidth="50" />
                    <el-table-column v-for="(a, i) in tableItems_end" :key="i" :prop="a.prop" :label="a.label"
                        :width="a.width || false" :minWidth="a.minWidth || false" show-overflow-tooltip />
                </el-table>
            </div>
            <div class="sg-pagination">
                <el-pagination background :hidden="endPage.total <= 10" :layout="layout" :page-sizes="[10, 20, 50]"
                    :pager-count="5" :current-page.sync="endPage.currentPage" :page-size.sync="endPage.pageSize"
                    :total="endPage.total" @size-change="initListEnd" @current-change="initListEnd" />
            </div>
        </div>
    </div>
</template>
    
<script>
export default {
    name: 'sgTransfer',
    data() {
        return {
            width: '200px',
            layout: `total, sizes, prev, pager, next, jumper`,
            disabledForm: false,
            inputSearchValue_start: '',
            inputSearchValue_end: '',
            tableItems_start: [],//表格列配置项
            tableItems_end: [],//表格列配置项
            tableData_start: [],//呈现的当前页数据
            tableData_end: [],//呈现的当前页数据
            tableData_end_bk: [],//最终选择的数据
            selection_start: [],
            selection_end: [],
            startPage: { currentPage: 1, pageSize: 10, total: 0, },
            endPage: { currentPage: 1, pageSize: 10, total: 0, },
            mainKey: null,//主键
        }
    },
    props: [
        "value",
        "data",
        /*格式说明
         data: {
              width: '400px',//表格宽度
              layout: `total, sizes, prev, next, jumper`,//翻页器显示控件
              // 列配置项
              tableItems: [
              { prop: 'ID', label: '工号', minWidth: '50' },
              { prop: 'XM', label: '姓名', minWidth: '50' },
              { prop: 'YHM', label: '用户名', minWidth: '50' },
              ],
              tableData: [],//表格显示内容
              startPage: { total: 0, },//实际总数
        }, */
        "titles",
        "buttonTexts",
        "filterPlaceholder",
    ],
    computed: {
        disabledLeftButton(d) {
            return this.selection_end.length === 0;
        },
        disabledRightButton(d) {
            // 在左边表格选中项里面,遍历每一项,如果在右侧表格中都能找到匹配项就true
            return this.selection_start.every(row => this.tableData_end_bk.some(v => this.isSameItem(v, row)));
        },
    },
    watch: {
        value: {
            handler(d) {
                this.inputSearchValue_start = '';
                this.inputSearchValue_end = '';
                this.startPage.currentPage = 1;
                this.endPage.currentPage = 1;
                this.tableData_end_bk = d || [];
                this.initListStart();
            }, deep: true, immediate: true,
        },
        data: {
            handler(d) {
                if (d) {
                    d.width && (this.width = d.width);
                    d.layout && (this.layout = d.layout);
                    this.tableData_start = d.tableData;
                    this.tableItems_start = d.tableItems_start || d.tableItems;
                    this.tableItems_end = d.tableItems_end || d.tableItems;
                    this.mainKey = (this.tableItems_start.find(v => v.mainKey) || {}).prop;//主键
                    this.startPage.total = (d.startPage || {}).total || 0;
                }
            }, deep: true, immediate: true,
        },
        tableData_end_bk: {
            handler(d) {
                this.$emit(`input`, d);
                this.initListEnd();
                if (this.tableData_end.length === 0) {
                    this.inputSearchValue_end = '';
                    this.endPage.currentPage = Math.round(this.tableData_end_bk.length / this.endPage.pageSize);
                }
            }, deep: true, immediate: true,
        },
    },
    methods: {
        row_click_start(row, column, event) { this.$refs.table_start.toggleRowSelection(row); },
        row_click_end(row, column, event) { this.$refs.table_end.toggleRowSelection(row); },
        pageChange(d) { this.initListStart(); this.$nextTick(() => { this.refreshCheckStatus() }); },
        refreshCheckStatus() {
            this.tableData_start.forEach(row => this.$refs.table_start.toggleRowSelection(row, this.tableData_end_bk.some(v => this.isSameItem(v, row))));
        },
        selectable(row) { return !this.tableData_end_bk.some(v => this.isSameItem(v, row)); },
        row_class_name({ row, rowIndex }) { return this.tableData_end_bk.find(v => this.isSameItem(v, row)) ? 'selected' : ''; },
        isSameItem(a_obj, b_obj) {
            let isSame = true;
            if (this.mainKey) {
                isSame = a_obj[this.mainKey] == b_obj[this.mainKey];
            } else {
                isSame = Object.keys(a_obj).every(k => a_obj[k] == b_obj[k]);
            }
            return isSame;
        },
        remove(d) {
            if (this.mainKey) {
                let selection_end_mainKeys = this.selection_end.map(v => v[this.mainKey]);
                this.tableData_end_bk = this.tableData_end_bk.filter(v => !selection_end_mainKeys.includes(v[this.mainKey]));
            } else {
                let selection_end = this.selection_end.map(v => JSON.stringify(v));
                this.tableData_end_bk = this.tableData_end_bk.filter(v => !selection_end.includes(JSON.stringify(v)));
            }
            this.$nextTick(() => { this.refreshCheckStatus() });
        },
        add(d) {
            this.selection_start.forEach(row => this.tableData_end_bk.some(v => this.isSameItem(v, row)) || this.tableData_end_bk.push(row));
        },
        selection_start_change(selection) {
            this.selection_start = selection;
        },
        selection_end_change(selection) {
            this.selection_end = selection;
        },
        initListStart() {
            this.$emit('init', {
                keyword: this.inputSearchValue_start,
                currentPage: this.startPage.currentPage || 1,
                pageSize: this.startPage.pageSize,
            });
        },
        initListEnd({
            keyword = this.inputSearchValue_end,
            currentPage = this.endPage.currentPage || 1,
            pageSize = this.endPage.pageSize,
        } = {}) {
            this.endPage.currentPage = currentPage;
            this.endPage.pageSize = pageSize;
            let results = this.tableData_end_bk.filter(obj =>
                keyword ?
                    Object.keys(obj).some(k => obj[k].toString().toLocaleLowerCase().includes(keyword.toString().toLocaleLowerCase()))
                    : true);
            this.endPage.total = results.length;
            this.tableData_end = results.slice((currentPage - 1) * pageSize, (currentPage) * pageSize);
        },

    },
};
</script>
    
<style lang="scss" scoped>
.sgTransfer {
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    white-space: nowrap;

    &>.sg-start,
    &>.sg-end {
        border: 1px solid #ebeef5;
        border-radius: 4px;
        overflow: hidden;
        background: #fff;
        display: inline-block;
        vertical-align: middle;
        max-height: 100%;
        box-sizing: border-box;
        position: relative;

        .sg-title {
            height: 40px;
            line-height: 40px;
            background: #f5f7fa;
            margin: 0;
            padding-left: 15px;
            border-bottom: 1px solid #ebeef5;
            box-sizing: border-box;
            color: #000;
        }

        .sg-search {
            box-sizing: border-box;
            padding: 10px;
        }

        .sg-table {}

        .sg-pagination {
            height: 50px;
            display: flex;
            justify-content: center;
            width: 100%;
            box-sizing: border-box;
            padding: 10px;
        }

    }

    &>.sg-center {
        margin: 0 10px;
    }

    &>.sg-end {}
}

>>>.el-table {
    tr.selected {
        filter: brightness(0.95);
        pointer-events: none;
    }

    .el-table__cell.gutter {
        border-bottom: 1px solid #EBEEF5;
        background-color: #f5f7fa;
    }
}
</style>

用例

<template>
  <div>
    <sgTransfer v-model="transferValue" :data="transferData" :titles="['所有用户', '本组成员']" :button-texts="['到左边', '到右边']"
      :filter-placeholder="`请输入工号、姓名…`" @init="initTransfer" />

    <hr>

    <div>
      <h1>勾选的数据transferValue:</h1>
      <div v-html="JSON.stringify(transferValue).replace(/\,\{/g, ',\n{')"
        style="word-wrap: break-word;word-break: break-all;white-space: break-spaces;"> </div>
    </div>
  </div>
</template>
  
<script>
import sgTransfer from "@/vue/components/admin/sgTransfer";

export default {
  components: { sgTransfer },
  data() {
    return {
      // 穿梭框配置项
      transferValue: [],
      transferData: {
        width: '400px',//表格宽度
        layout: `total, sizes, prev, next, jumper`,//翻页器显示控件
        // 列配置项
        tableItems: [
          { prop: 'ID', label: '工号', minWidth: '50', mainKey: true },//设置主键
          { prop: 'XM', label: '姓名', minWidth: '50' },
          { prop: 'YHM', label: '用户名', minWidth: '50' },
        ],
        tableData: [],//表格显示内容
        startPage: { total: 0, },//实际总数
      },

      // 渲染数据
      tableData: [],
      tableData_bk: [],
      userList: [
        { key: 1, label: '梁冰露' },
        { key: 2, label: '吴梵听' },
        { key: 3, label: '卢令美' },
        { key: 4, label: '韩宛曼' },
        { key: 5, label: '郝海冬' },
        { key: 6, label: '傅优悦' },
        { key: 7, label: '郝幻莲' },
        { key: 8, label: '江嘉云' },
        { key: 9, label: '梁秋芳' },
        { key: 10, label: '郝悦颖' },
        { key: 11, label: '廖芝蓉' },
        { key: 12, label: '胡傲丝' },
        { key: 13, label: '赵珺琦' },
        { key: 14, label: '石心诺' },
        { key: 15, label: '丁翠芙' },
        { key: 16, label: '李夏河' },
        { key: 17, label: '范水悦' },
        { key: 18, label: '郑凝雪' },
        { key: 19, label: '李亦玉' },
        { key: 20, label: '袁三春' },
        { key: 21, label: '赵红叶' },
        { key: 22, label: '曹安琪' },
        { key: 23, label: '谭琴音' },
        { key: 24, label: '钟湛蓝' },
        { key: 25, label: '陆之柔' },
        { key: 26, label: '吕孒凡' },
        { key: 27, label: '熊野雪' },
        { key: 28, label: '曹叶澜' },
        { key: 29, label: '韩粟梅' },
        { key: 30, label: '孔杏儿' },
        { key: 31, label: '宋若彤' },
        { key: 32, label: '于淼淼' },
        { key: 33, label: '潘欣跃' },
        { key: 34, label: '石雅辰' },
        { key: 35, label: '白念珍' },
        { key: 36, label: '文爱茹' },
        { key: 37, label: '王如曼' },
        { key: 38, label: '宋丝琪' },
        { key: 39, label: '王凝荷' },
        { key: 40, label: '郑雨雪' },
        { key: 41, label: '梁映阳' },
        { key: 42, label: '徐新雨' },
        { key: 43, label: '毛恬雅' },
        { key: 44, label: '侯若蕊' },
        { key: 45, label: '杨云蔚' },
        { key: 46, label: '史之卉' },
        { key: 47, label: '胡千束' },
        { key: 48, label: '冯冷荷' },
        { key: 49, label: '金语心' },
        { key: 50, label: '江恬默' },
        { key: 51, label: '高香馨' },
        { key: 52, label: '江凌晴' },
        { key: 53, label: '梁列琴' },
        { key: 54, label: '邹鸾瑶' },
        { key: 55, label: '夏素洁' },
        { key: 56, label: '范秋玉' },
        { key: 57, label: '钟北嘉' },
        { key: 58, label: '谭水云' },
        { key: 59, label: '顾山柏' },
        { key: 60, label: '龙曼蔓' },
        { key: 61, label: '钟双儿' },
        { key: 62, label: '林林娜' },
        { key: 63, label: '邹溪儿' },
        { key: 64, label: '顾妙彤' },
        { key: 65, label: '傅茵茵' },
        { key: 66, label: '卢念露' },
        { key: 67, label: '罗冷亦' },
        { key: 68, label: '胡秋颖' },
        { key: 69, label: '姜怡月' },
        { key: 70, label: '傅和暄' },
        { key: 71, label: '赖布凡' },
        { key: 72, label: '郝念蕾' },
        { key: 73, label: '邱天欣' },
        { key: 74, label: '汤莉莉' },
        { key: 75, label: '段靖易' },
        { key: 76, label: '周之云' },
        { key: 77, label: '董映秋' },
        { key: 78, label: '汤玲琅' },
        { key: 79, label: '田雁梅' },
        { key: 80, label: '石雨雪' },
        { key: 81, label: '任君雅' },
        { key: 82, label: '蔡小谷' },
        { key: 83, label: '孟忆之' },
        { key: 84, label: '姜闲丽' },
        { key: 85, label: '文忆香' },
        { key: 86, label: '戴运虹' },
        { key: 87, label: '王玄穆' },
        { key: 88, label: '刘绿柳' },
        { key: 89, label: '萧梦丝' },
        { key: 90, label: '谭忆山' },
        { key: 91, label: '方榕嫣' },
        { key: 92, label: '徐欣合' },
        { key: 93, label: '夏雨南' },
        { key: 94, label: '尹沙羽' },
        { key: 95, label: '万梦玉' },
        { key: 96, label: '谢灵枫' },
        { key: 97, label: '曾源源' },
        { key: 98, label: '赖谷枫' },
        { key: 99, label: '彭子童' },
      ],
    }
  },
  created() {
    this.createTableData()
  },
  methods: {
    // 初始化、翻页、切换每页显示数量的时候触发
    initTransfer({ keyword = '', currentPage = 1, pageSize = 10 } = {}) {
      // 模拟接口调用----------------------------------------
      let results = this.tableData_bk.filter(obj => keyword ? Object.keys(obj).some(k => obj[k].toString().toLocaleLowerCase().includes(keyword.toString().toLocaleLowerCase())) : true);
      this.transferData.startPage.total = results.length;
      this.transferData.tableData = results.slice((currentPage - 1) * pageSize, (currentPage) * pageSize);
      // ----------------------------------------
    },
    // 构建数据
    createTableData(d) {
      this.tableData_bk = this.userList.map(v => {
        let ID = this.$g.getRandomID();
        return { ID, XM: v.label, YHM: `user${ID}`, }
      });
      this.initTransfer();
    },
  }
}
</script>

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

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

相关文章

AMEYA360代理 | 佰维eMMC、LPDDR存储芯片赋能电视终端流畅体验

5G、AI、VR、AR等技术的发展&#xff0c;助推智能电视、机顶盒等电视终端成为智能家居领域不可忽视的重要设备。随着4K超高清(UHD)技术、虚拟现实技术(VR)和增强现实技术(AR)的普及&#xff0c;并向8K超高清技术不断渗透&#xff0c;电视终端将可以为消费者提供更清晰的视觉体验…

mapboxGL3新特性介绍

概述 8月7日&#xff0c;mapboxGL发布了3版本的更新&#xff0c;本文带大家一起来看看mapboxGL3有哪些新的特性。 新特新 如上图所示&#xff0c;是mapboxGL官网关于新版的介绍&#xff0c;大致翻译如下&#xff1a; 增强了web渲染的质量、便捷程度以及开发人员体验&#xff…

前端面试中Vue的有经典面试题一

1. 谈谈你对MVVM开发模式的理解 MVVM分为Model、View、ViewModel三者。 Model&#xff1a;代表数据模型&#xff0c;数据和业务逻辑都在Model层中定义&#xff1b; View&#xff1a;代表UI视图&#xff0c;负责数据的展示&#xff1b; ViewModel&#xff1a;负责监听Model中…

Matlab(画图初阶)

目录 1.plot()函数 2. hold(添加新绘图是否保留旧绘图) 3. Plot Style 3.1 线型 3.2 标记 3.3 颜色 ​编辑 4. legend() 5.X 、Y and Title&#xff1f; 6. Text()和annotation() 7.line(创建基本线条) 7.1 基本语法 7.2 指定线条属性 7.3 更改线条属性 8.图像属性 8.1 …

HttPClient简介及示例:学习如何与Web服务器进行通信

文章目录 前言一、引入依赖二、使用步骤1.创建被调用者2.创建调用者三、结果被调用者服务&#xff1a;调用者服务&#xff1a; 总结 前言 欢迎来到本篇博客&#xff0c;这是一个关于HttPClient的入门案例的指南。&#x1f389; 在今天的网络世界中&#xff0c;与服务器进行数据…

精品基于SpringCloud实现的电影院购票系统设计-微服务-分布式

《[含文档PPT源码等]精品基于SpringCloud实现的电影院购票系统设计的设计与实现-微服务-分布式》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程等 软件开发环境及开发工具&#xff1a; 开发语言&#xff1a;Java 框架&#xff1a;springcloud JDK版…

JavaScript运行机制与实践应用

一、JavsScript运行机制 1、JavaScript 是一种解释型语言&#xff0c;它的执行机制主要包括以下几个步骤&#xff1a; 2、事件循环 3、JavaScript运行模型 4、JavaScript任务 5、JavaScript宏任务和微任务 6、案例分析 console.log(script start) setTimeout(function () {co…

同步与互斥

硬件指令 实现互斥&#xff1a;硬件指令&#xff0c;硬件实现的原子操作&#xff0c;不会被打断 tsl指令和xchg指令 当前指令执行完&#xff0c;才会检测中断 If the signal comes while an instruction is being executed, it is held until the execution of the instructi…

Mac 多版本jdk安装与切换

macOS上可以安装多个版本的jdk&#xff0c;方法如下&#xff1a; 1.下载jdk 在Oracle官网上下载不同版本的jdk&#xff1a; https://www.oracle.com/java/technologies/downloads/#java17 方案一 1.查看本机所有的jdk /usr/libexec/java_home -V3. 配置环境变量 打开bash_…

面经:安卓学习笔记

文章目录 1. Android系统架构2. Activity2.0 定义2.1 生命周期2.2 生命状态2.3 启动模式 3. Service3.1 定义3.2 两种启动方式3.3 生命周期3.4 跨进程service3.5 IntentService 4. BroadCastReceiver4.1 概念4.2 组成4.3 广播接收器的分类4.4 生命周期4.5 静态注册和动态注册 5…

游戏发行商能够提供什么服务?

游戏发行商可以为游戏开发者提供广泛的服务&#xff0c;以帮助他们将游戏成功地引入市场并取得更好的业绩。以下是游戏发行商可能提供的一些服务&#xff1a; 市场营销和宣传&#xff1a;发行商通常具有丰富的市场营销经验&#xff0c;可以制定并执行有效的宣传和营销策略。他们…

深度学习推荐系统(五)DeepCrossing模型及其在Criteo数据集上的应用

深度学习推荐系统(五)Deep&Crossing模型及其在Criteo数据集上的应用 在2016年&#xff0c; 随着微软的Deep Crossing&#xff0c; 谷歌的Wide&Deep以及FNN、PNN等一大批优秀的深度学习模型被提出&#xff0c; 推荐系统全面进入了深度学习时代&#xff0c; 时至今日&am…

githubPage部署Vue项目

github中新建项目 my-web &#xff08;编写vue项目代码&#xff09; myWebOnline(存放Vue打包后的dist包里面的文件) 发布流程 &#xff08;假设my-web项目已经编写完成&#xff09;Vue-cli my-web vue.config.js文件中 const { defineConfig } require(vue/cli-service)…

常用的msvcp140.dll丢失的解决方法,msvcp140.dll丢失的原因

自从电脑出现故障&#xff0c;我的生活变得一团糟。他每天都需要使用电脑处理工作&#xff0c;可是突然有一天&#xff0c;他发现许多软件和游戏都无法正常运行。错误提示显示“找不到msvcp140.dll”&#xff0c;这让他感到非常困扰。今天想和大家分享一个在计算机使用过程中经…

【Linux】简单的小程序:进度条

在学习进度条之前&#xff0c;需要学一点预备知识。 1. 预备知识 回车换行 现在的换行符&#xff08;\n&#xff09;其实就是回车式换行符&#xff0c;另起一行&#xff0c;光标指向最新一行的开头。回车符&#xff08;\r&#xff09;是光标指向这一行的开头。 缓冲区 &a…

OpenCV(十一):图像仿射变换

目录 1.图像仿射变换介绍 仿射变换&#xff1a; 仿射变换矩阵&#xff1a; 仿射变换公式&#xff1a; 2.仿射变换函数 仿射变换函数&#xff1a;warpAffine() 图像旋转&#xff1a;getRotationMatrix2D() 计算仿射变换矩阵&#xff1a;getAffineTransform() 3.demo 1.…

飞腾平台芯片测试固件(SFW)和开机启动log

一、说两句 最近公司飞腾产品越来越多了&#xff0c;FT-2000/4的D2000的X100的&#xff0c;最近又新出了E2000。越来越多新来的小孩儿开始加入到飞腾的调测试中&#xff0c;那么在他们实际的调试中会遇到很多的问题。在固件启动阶段有的板卡会有一些异常&#xff0c;有时我们需…

一文1800字从0到1使用Python Flask实战构建Web应用

Python Flask是一个轻量级的Web框架&#xff0c;它简单易用、灵活性高&#xff0c;适用于构建各种规模的Web应用。本文将介绍如何使用Python Flask框架来实战构建一个简单的Web应用&#xff0c;并展示其基本功能和特性。 第一部分&#xff1a;搭建开发环境 在开始之前我们需要…

软件测试人员在工作中如何运用Linux

从事过软件测试的小伙们就会明白会使用Linux是多么重要的一件事&#xff0c;工作时需要用到&#xff0c;面试时会被问到&#xff0c;简历中需要写到。 对于软件测试人员来说&#xff0c;不需要你多么熟练使用Linux所有命令&#xff0c;也不需要你对Linux系统完全了解&#xff…

Linux x86_64 C语言实现gdb断点机制

文章目录 前言一、trap指令简介二、调用ptrace三、创建breakpoints四、CONT 和 SINGLESTEP五、完整代码演示六、增加参数检测参考资料 前言 本文参考文章&#xff1a;Implementing breakpoints on x86 Linux 一、trap指令简介 将通过在断点地址向目标进程的内存中插入一条新…