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

news2024/7/6 18:57:55

 

特性: 

  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, },
        }
    },
    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) {
                if (d) {
                    this.tableData_end = d || [];
                    this.initListEnd();
                }
            }, 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.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,
        },
    },
    created() {
        this.initListStart();
    },
    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; Object.keys(a_obj).forEach(k => a_obj[k] !== b_obj[k] && (isSame = false));
            return isSame
        },
        remove(d) {
            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;
        },
        someTableItem({ keyword, obj }) {
            return Object.keys(obj).some(k => obj[k].toString().includes(keyword));
        },
        initListStart() {
            this.$emit('init', {
                keyword: this.inputSearchValue_start,
                currentPage: this.startPage.currentPage,
                pageSize: this.startPage.pageSize,
            });
        },
        initListEnd({
            keyword = this.inputSearchValue_end,
            currentPage = this.endPage.currentPage,
            pageSize = this.endPage.pageSize,
        } = {}) {
            this.endPage.currentPage = currentPage;
            this.endPage.pageSize = pageSize;
            let results = this.tableData_end_bk.filter(obj => keyword ? this.someTableItem({ keyword, obj }) : 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="data" :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: [],
      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, },//实际总数
      },

      // 渲染数据
      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((v, i, ar) => keyword ? v.XM.includes(keyword) || v.ID.includes(keyword) : true);
      this.data.startPage.total = results.length;
      this.data.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>

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

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

相关文章

渲染如何做到超强渲染?MAX插件CG MAGIC中的渲染功能!

渲染工作应该算是设计师的日常工作流程中最重要的环节之一了。如果渲染速度加快&#xff0c;可能是要看渲染技巧掌握的有多少了。 大家熟悉的3d Max本地渲染通道&#xff0c;对于CG MAGIC渲染功能你也一定不能错过&#xff0c;要知道操作简单易使用&#xff0c;就完全拿捏了效率…

防溺水智能预警系统解决方案 yolov7

防溺水智能预警系统解决方案采用yolov7先进的AI视觉识别算法模型框架&#xff0c;防溺水智能预警系统解决方案算法实现对危险水域人员活动、水面情况等各项指标的监测和分析。当发现有人进入危险水域或出现紧急情况时&#xff0c;算法会立即发出预警信号。Yolo算法采用一个单独…

c#继承(new base)的使用

概述 C#中的继承是面向对象编程的重要概念之一&#xff0c;它允许一个类&#xff08;称为子类或派生类&#xff09;从另一个类&#xff08;称为父类或基类&#xff09;继承属性和行为。 继承的主要目的是实现代码重用和层次化的组织。子类可以继承父类的字段、属性、方法和事…

MySQL忘记密码->重置密码

MySQL忘记密码->重置密码 无密码登录root 以管理员权限进入CMD&#xff0c;在命令行输入&#xff1a;net stop mysql MySQL停止服务后&#xff0c;输入mysqld --shared-memory --skip-grant-tables&#xff0c;以锁定命令提示符窗口&#xff0c;我们需要重新打开一个管理员…

vivo2020届春季校园招聘在线编程考试(一)

题目&#xff1a; 手机屏幕解锁模式 现有一个 3x3 规格的 Android 智能手机锁屏程序和两个正整数 m 和 n &#xff0c;请计算出使用最少m 个键和最多 n个键可以解锁该屏幕的所有有效模式总数。 其中有效模式是指&#xff1a; 1、每个模式必须连接至少m个键和最多n个键&#xf…

Sharding-JDBC(八)5.3 系列升级解读

目录 一、背景二、影响范围1.Maven 坐标调整2.自定义算法调整3.事务调整4.配置文件调整 三、升级指导1.新的 ShardingSphereDriver 数据库驱动2.正在使用 Spring Boot Starter 如何升级升级前升级后 3.正在使用 Spring Namespace 如何升级升级前升级后 四、总结 5.3.0 官方文档…

实训笔记8.30

实训笔记8.30 8.30笔记一、项目开发流程一共分为七个阶段1.1 数据产生阶段1.2 数据采集存储阶段1.3 数据清洗预处理阶段1.4 数据统计分析阶段1.5 数据迁移导出阶段1.6 数据可视化阶段 二、项目数据清洗预处理的实现2.1 清洗预处理规则2.2 代码实现 三、项目的数据统计分析阶段3…

Linux通信--构建进程通信IPC的方案之共享内存|实现使用共享内存进行serverclient通信

共享内存是最快的IPC形式。一旦这样的内存映射到共享它的进程地址空间&#xff0c;这些进程间数据传递不再涉及到内核&#xff0c;即进程不再通过执行进入内核的系统调用来传递彼此的数据。 目录 一、共享内存的原理 二、使用共享内存 三、共享内存函数 1.shmget(用来创建共…

字节跳动岗位的薪酬体系曝光,看完感叹:真的不服不行

曾经的互联网是PC的时代&#xff0c;随着智能手机的普及&#xff0c;移动互联网开始飞速崛起。而字节跳动抓住了这波机遇&#xff0c;2015年&#xff0c;字节跳动全面加码短视频&#xff0c;从那以后&#xff0c;抖音成为了字节跳动用户、收入和估值的最大增长引擎。 自从字节…

Web3数据云OORT推出商用版智能代理构建平台:OORT TDS

随着技术进步和数据隐私问题的日益凸显&#xff0c;生成式AI和去中心化技术联手为企业和个人开辟了全新的互动视野。站在这一趋势的前沿&#xff0c;OORT展现了其在去中心化数据云领域的技术实力&#xff0c;作为行业的领先者&#xff0c;今日Oort正式宣布OORT TDS (Talk-to-Da…

MAGNA 直连 EDI 解决方案

全球首屈一指的汽车零部件供应商&#xff0c;在28个国家设有335家制造工厂&#xff0c;96个产品开发、工程和销售中心。产品主要包括制造车身、底盘、外饰、座椅、动力总成、电子、主动驾驶辅助、镜像、闭锁以及车顶系统&#xff0c;拥有多个领域的电子和软件工程能力。 MAGNA与…

row_number() over(partition by xx order by xx desc)

一、目的 主要用于根据某个字段对数据分组去重 二、demo 1. 有数据表 duplicate_test 如下 2. 使用 name 作为 key 对数据分组&#xff0c;并增加一列标识序号 idx&#xff08;根据 时间戳倒序标记序号&#xff09; select name,row_number() over(partition by name order…

IT6225B芯片方案|替代IT6225B方案|CS5366国产Typec转hdmi投屏方案

国产CS5366 透过模拟与数字的设计及28nm先进制程工艺,大幅降低功耗,无需增加散热片,提高产品可靠性,CS5366完全替代联阳IT6225B/IT6225,CS5366是一款Type-C转HDMI 2.0 4K60USB 3.0PD3.1/3.0高集成度视频转换芯片方案. 1.cs5366功耗低&#xff1a; CS5366系列符合USB电源传输规…

TCP数据报结构分析(面试重点)

在传输层中有UDP和TCP两个重要的协议&#xff0c;下面将针对TCP数据报的结构进行分析 关于UDP数据报的结构分析推荐看UDP数据报结构分析&#xff08;面试重点&#xff09; TCP结构图示 TCP报头结构的分析 一.16位源端口号 源端口表示发送数据时&#xff0c;发送方的端口号&am…

IO模型:阻塞和非阻塞

一、五种IO模型------读写外设数据的方式 阻塞: 不能操作就睡觉 非阻塞&#xff1a;不能操作就返回错误 多路复用&#xff1a;委托中介监控 信号驱动&#xff1a;让内核如果能操作时发信号&#xff0c;在信号处理函数中操作 异步IO&#xff1a;向内核注册操作请求&…

ES+Redis+MySQL,这个高可用架构设计太顶了!

目录 背景ES 高可用方案会员 Redis 缓存方案高可用会员主库方案异常会员关系治理展望&#xff1a;更精细化的流控和降级策略 背景 会员系统是一种基础系统&#xff0c;跟公司所有业务线的下单主流程密切相关。如果会员系统出故障&#xff0c;会导致用户无法下单&#xff0c;…

RS485隔离电路方案

RS485总线是一种使用平衡发送&#xff0c;差分接收实现通讯的通用串口通信总线&#xff0c;由于其具有抗共模干扰能力强、成本低、抗噪能力强、传输距离远、传输速率高、可连接多达256个收发器等优点&#xff0c;广泛应用于工业智能仪表&#xff0c;通讯设备等各个领域。 RS485…

Flutter:getX的学习

前言 学习教程&#xff1a;Getx教程_FlutterGetx系列实战教程 简介 getX是第三方的状态管理插件&#xff0c;不仅具有状态管理的功能&#xff0c;还具有路由管理、主题管理、国际化多语言管理、网络请求、数据验证等功能。相比其他状态管理组件&#xff0c;getX简单、功能强大…

JDK源码解析-Object

1. Object类 所有类的基类——java.lang.Object Object 类是所有类的基类&#xff0c;当一个类没有直接继承某个类时&#xff0c;默认继承Object类Object 类属于 java.lang 包&#xff0c;此包下的所有类在使用时无需手动导入&#xff0c;系统会在程序编译期间自动导入。 思…

(二)范数与距离

本文主要内容如下&#xff1a; 1. 范数的定义2. 常见的范数举例3. 范数的等价4. 距离与度量空间的定义 1. 范数的定义 定义1-1&#xff1a;设 E E E 为向量空间&#xff0c; R \mathbb{R} R 为实数域。若映射 ∥ ⋅ ∥ : E → R : x ↦ ∥ x ∥ \begin{equation*} \lVert\cd…