【vue2】element-ui el-transfer扩展 实现多列效果一对多

这篇具有很好参考价值的文章主要介绍了【vue2】element-ui el-transfer扩展 实现多列效果一对多。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

vue2 el-transfer 穿梭框实现多类别


一、效果图

【vue2】element-ui el-transfer扩展 实现多列效果一对多,ui,javascript,vue.js

二、具体实现

1.重写组件

创建一个组件extends至element-ui的Transfer

template

复制Transfer源码中的template,并拓展我们需要的列表2和button

    <div class="el-transfer">
        <transfer-panel v-bind="$props" ref="leftPanel" :data="sourceData" :title="titles[0] || t('el.transfer.titles.0')"
            :default-checked="leftDefaultChecked" :placeholder="filterPlaceholder || t('el.transfer.filterPlaceholder')"
            @checked-change="onSourceCheckedChange">
            <slot name="left-footer"></slot>
        </transfer-panel>
        <div class="el-transfer__buttons">
            <div>
                <el-button type="primary" :class="['el-transfer__button', hasButtonTexts ? 'is-with-texts' : '']"
                    @click.native="addToLeft" :disabled="listTwoChecked.length === 0 && rightChecked.length === 0">
                    <i class="el-icon-arrow-left"></i>
                    <span v-if="buttonTexts[0] !== undefined">{{ buttonTexts[0] }}</span>
                </el-button>
            </div>
            <div>
                <el-button type="primary" :class="['el-transfer__button', hasButtonTexts ? 'is-with-texts' : '']"
                    @click.native="addToRight" :disabled="leftChecked.length === 0">
                    <span v-if="buttonTexts[1] !== undefined">{{ buttonTexts[1] }}</span>
                    <i class="el-icon-arrow-right"></i>
                </el-button>
            </div>
            <div>
            <!-- 新增的button -->
                <el-button type="primary" :class="['el-transfer__button', hasButtonTexts ? 'is-with-texts' : '']"
                    @click.native="addToListTwo" :disabled="leftChecked.length === 0">
                    <span v-if="buttonTexts[1] !== undefined">{{ buttonTexts[2] }}</span>
                    <i class="el-icon-arrow-right"></i>
                </el-button>
            </div>
            <slot name="buttons"></slot>
        </div>
        <transfer-panel v-bind="$props" ref="rightPanel" :data="targetData" :title="titles[1] || t('el.transfer.titles.1')"
            :default-checked="rightDefaultChecked" :placeholder="filterPlaceholder || t('el.transfer.filterPlaceholder')"
            @checked-change="onTargetCheckedChange">
            <slot name="right-footer"></slot>
        </transfer-panel>
        <!-- 新增的list -->
        <transfer-panel class="m-l-20" v-bind="$props" ref="rightPanel" :data="listTwoData"
            :title="titles[2] || t('el.transfer.titles.1')" :default-checked="listTwoDefaultChecked"
            :placeholder="filterPlaceholder || t('el.transfer.filterPlaceholder')"
            @checked-change="onlistTwoCheckedChange">
            <slot name="right-footer"></slot>
        </transfer-panel>
    </div>

script

这里重写了Transfer的addToLeft方法,按着element-ui的逻辑写出第二个列表的逻辑即可。源码就不做解释了,这个组件比较简单,感兴趣的朋友可以去看看

import { Transfer } from 'element-ui'

export default {
    extends: Transfer,
    props: {
        listTwo: {
            type: Array,
            default: () => []
        },
        listTwoDefaultChecked: {
            type: Array,
            default: () => []
        },
    },
    data() {
        return {
            // 列表2选中的数据
            listTwoChecked: []
        };
    },
    computed: {
        listTwoData() {
            if (this.targetOrder === 'original') {
                return this.data.filter(item => this.listTwo.indexOf(item[this.props.key]) > -1);
            } else {
                return this.listTwo.reduce((arr, cur) => {
                    const val = this.dataObj[cur];
                    if (val) {
                        arr.push(val);
                    }
                    return arr;
                }, []);
            }
        },
        sourceData() {
            return this.data.filter(item => this.value.indexOf(item[this.props.key]) === -1
                && this.listTwo.indexOf(item[this.props.key]) === -1);
        },
    },
    methods: {
        addToListTwo() {
            let currentValue = this.listTwo.slice();
            const itemsToBeMoved = [];
            const key = this.props.key;
            this.data.forEach(item => {
                const itemKey = item[key];
                if (
                    this.leftChecked.indexOf(itemKey) > -1 &&
                    this.listTwo.indexOf(itemKey) === -1
                ) {
                    itemsToBeMoved.push(itemKey);
                }
            });
            currentValue = this.targetOrder === 'unshift'
                ? itemsToBeMoved.concat(currentValue)
                : currentValue.concat(itemsToBeMoved);
            console.debug(currentValue);
            // 更新列表2
            this.$emit('update:listTwo', currentValue);
        },
        // 列表2设备选择
        onlistTwoCheckedChange(val, movedKeys) {
            this.listTwoChecked = val;
            if (movedKeys === undefined) return;
            this.$emit('right-check-change', val, movedKeys);
        },
        addToLeft() {
            // 列表1
            let currentValue = this.value.slice();
            // 列表2
            let listTwo = this.listTwo.slice();
            this.rightChecked.forEach(item => {
                const index = currentValue.indexOf(item);
                if (index > -1) {
                    currentValue.splice(index, 1);
                }
            });
            this.listTwoChecked.forEach(item => {
                const index = listTwo.indexOf(item);
                if (index > -1) {
                    listTwo.splice(index, 1);
                }
            });
            // 更新列表1
            this.$emit('input', currentValue);
            // 更新列表2
            this.$emit('update:listTwo', listTwo);
            this.$emit('change', currentValue, 'left', this.rightChecked);
        },
    },
    watch: {
        listTwo(val) {
            this.dispatch('ElFormItem', 'el.form.change', val);
        },
    }
}

style

.m-l-20{
    margin-left: 20px;
}

GitHub地址文章来源地址https://www.toymoban.com/news/detail-714154.html


总结

还有些细节没有处理,比如list2的事件。

到了这里,关于【vue2】element-ui el-transfer扩展 实现多列效果一对多的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue2+element-ui,el-aside侧边栏容器收缩与展开

    一、概览 实现效果如下: 二、项目环境 1、nodejs版本 2、npm版本 3、vue脚手架版本 三、创建vue项目 1、创建名为vuetest的项目 选择Default([Vue2] babel,eslint)    2、切换到项目目录,启动项目   3、使用浏览器预览  http://localhost:8080/ 四、使用Visual Studio Code打开项目 1、查看源码

    2023年04月22日
    浏览(39)
  • Vue2.0+Element-ui(2.15.13)出现el-table不显示问题解决方案

    遇到的问题: Element-ui中的 el-table组件 无法正常显示; 1.安装的Vue是2.0版本; 2.安装的Element-ui是2.15.13版本 原因: 1.一个项目调用了element-ui和vant两个ui库,有冲突; 2.Element-ui是2.15.13版本依赖比较高;   解决方案: 1.npm uninstall element-ui;下载Element-ui 2.npm install element-ui@2.8.3

    2024年02月11日
    浏览(55)
  • element el-transfer穿梭框的使用,自定义穿梭框的数据项

    1:查看element官方文档可以了解到 el-transfer穿梭框的基本使用方法,本文主要介绍数据项的自定义渲染和右侧列表元素变化时触发方法的实现。 自定义数据项,除了基本的el-transfer使用方法,还需要使用Scoped Slot。 实现效果 2: :render-content=“renderFunc” 既可以文字过长以点点

    2024年02月14日
    浏览(43)
  • Vue2.0安装Element-ui

    1.在项目终端输入 如果想知道是否安装成功   2.随后在main.js里引入element组件 然后去使用element   就这样成功了  

    2024年02月16日
    浏览(43)
  • 扩展element-ui el-upload组件,实现复制粘贴上传图片文件,带图片预览功能

    控件改造 在窗口的 el-form 控件参数中添加 @paste.native 事件,事件绑定方法名 handlePaste 也可以在其他控件中添加事件监听,看个人需求。 注意: 监听粘贴事件时,需要当前页面先获取焦点,否则无法正常监听, 可以在页面加载后调用 focus() 获取焦点 粘贴功能Js部分参考资料

    2023年04月08日
    浏览(100)
  • Vue2 +Element-ui实现前端页面

    以一个简单的前端页面为例。主要是利用vue和element-ui实现。 里面涉及的主要包括:新建vue项目、一行多个输入框、页面实现等。   ①首先安装nodejs,这部分在此就不讲啦。 ②然后安装vue-cli: 查看是否安装成功: 安装成功之后就输出vue的版本 ③在cmd窗口新建一个vue2脚手架

    2024年02月16日
    浏览(45)
  • Vue2 - 引入Element-UI组件样式

    官方文档 https://element.eleme.cn/#/zh-CN/component/installation 推荐使用 npm 的方式安装 ,它能更好地和 webpack 打包工具配合使用。 在终端cd到项目文件夹下安装 也可以通过CDN(不推荐) 目前可以通过 unpkg.com/element-ui 获取到最新版本的资源,在页面上引入 js 和 css 文件即可开始使用。

    2024年02月06日
    浏览(63)
  • vue2+element-ui 实现国际化

    在src目录下创建一个lang文件夹,同时创建zh.js(中文),en.js(英文),ja.js(日文),fr.js(法文)四个语言包js文件,并创建一个index.js文件,用来整合语言包 对于一个项目来说,一个语言包需要包含所有页面以及组件;在语言包以页面为单位,创建一个对象;对公共的title或者按钮名

    2024年02月02日
    浏览(55)
  • VUE2+Element-ui+封装Echarts图表

    封装Echarts图表,如下效果图 Home组件代码块,使用的mock.js模拟数据封装 Echarts图表组件 安装所需依赖 cnpm i axios -S 安装axios接口请求 cnpm i mockjs 或 yarn add mockjs 安装mockjs生成模拟随机数据 cnpm i echarts 或 yarn add echarts 安装echarts图表 cnpm i element-ui -S 安装element-ui组件库 安装less c

    2024年02月08日
    浏览(48)
  • vue2+element-ui实现侧边导航栏

    编写 client/src/components/LeftMenu.vue ,创建侧边导航栏: 编辑 client/src/views/Index.vue ,引入侧边导航栏:

    2024年02月02日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包