iView实现表格拖拽列宽度,列显示顺序及显示字段

需要实现表格列宽度调整,选择展示表格字段,以及显示顺序,先看效果,每次变动后保存到本地缓存中,也可以与后台配合保存到数据库,实现用户自定义表格.
在这里插入图片描述

1.安装vuedraggable实现拖拽

npm i vuedraggable

2.新建组件 FilterColumns.vue

我这里默认把操作列放到最后一个并且不允许编辑,如不需要可删除

<template>
  <RadioGroup type="button">
    <Radio title="筛选列">
      <Icon type="md-list" class="showColumn" @click="modalVisible = true">
      </Icon>
      <Modal
        title="筛选列"
        v-model="modalVisible"
        :mask-closable="false"
        :width="800"
      >
        <Form ref="form" inline>
          <FormItem style="width: 98%" class="showcolumns">
            <CheckboxGroup v-model="selectTitles" @on-change="changeColumns">
              <draggable
                v-model="sortTitles"
                chosenClass="active"
                animation="500"
                @end="changeColumns"
              >
                <Checkbox
                  v-for="(item, index) in sortTitles"
                  :key="index"
                  :label="item"
                  v-show="!['操作', 'undefined'].includes(item + '')"
                >
                  <span>{{ item }}</span>
                </Checkbox>
              </draggable>
            </CheckboxGroup>
          </FormItem>
        </Form>

        <div slot="footer">
          <Button type="text" @click="clear">重置</Button>
          <Button type="text" @click="modalVisible = false">取消</Button>
          <Button type="success" @click="reverseSelect">反选</Button>
        </div>
      </Modal>
    </Radio>
  </RadioGroup>
</template>

<script>
import draggable from "vuedraggable";
export default {
  name: "FilterColumns",
  components: { draggable },
  props: {
    columns: {
      type: Array,
      default: () => [],
    },
    cacheKey: {
      type: String,
      default: "",
    },
  },

  data() {
    return {
      key: "",
      modalVisible: false, // 添加或编辑显示
      selectTitles: [],
      sortTitles: [],
      widthTitles:{
        init:"0",
      },
    };
  },
  methods: {
    changeColumnsWidth(v){
      if(v){
        this.widthTitles[v[2].title] = v[0];
       this.changeColumns();
      }
    },
    clear(){
      this.removeStore(`select::${this.key}`);
      this.removeStore(`sort::${this.key}`);
      this.removeStore(`width::${this.key}`);
      this.init();
    },
    init() {
      //this.key = this.$route.name;
      if (this.cacheKey) {
        this.key = this.cacheKey;
      } else {
        this.key = this.$route.name;
      }
      this.initData();
      this.changeColumns();
    },
    initData() {
    //此处保存到本地缓存,可换成请求后台接口获取用户自定义数据
      let selectTitleStr = this.getStore(`select::${this.key}`);
      this.selectTitles = selectTitleStr && selectTitleStr != "[]"? JSON.parse(selectTitleStr) : [];
      let sortColumsStr = this.getStore(`sort::${this.key}`);
      this.sortTitles =
        sortColumsStr && sortColumsStr != "[]" ? JSON.parse(sortColumsStr) : [];
        let widthColumsStr = this.getStore(`width::${this.key}`);
      this.widthTitles =
      widthColumsStr && widthColumsStr != "{}" ? JSON.parse(widthColumsStr) : { init:"0"};
    },
    changeColumns() {
      var that = this;
      if (!!!this.sortTitles.length) {
        this.sortTitles = this.columns
          .map((item) => item.title)
          .filter((item) => item && item.title != "操作");
      }

      this.columns.forEach(item => {
        item.resizable = true;
        if(!item.width && item.minWidth){
            item.width = item.minWidth
        } else if(!item.width && !item.minWidth){
          item.width = 200;
        }
      });
      if (this.widthTitles.init=="0") {
        this.columns.forEach(item=>{
          that.widthTitles[item.title] = item.width;
        })
        that.widthTitles.init = "1";
      }
      //如果选中标题不存在则赋予全部
      if (!!!this.selectTitles.length) {
        this.selectTitles = JSON.parse(JSON.stringify(this.sortTitles));
      }
      //此处保存到本地缓存,可换成请求后台接口,保存至数据库
      this.setStore(`select::${this.key}`, JSON.stringify(this.selectTitles));
      this.setStore(`sort::${this.key}`, JSON.stringify(this.sortTitles));
      this.setStore(`width::${this.key}`, JSON.stringify(this.widthTitles));

      let currentColumns = this.columns
        .filter(
          (item) =>
            this.selectTitles.includes(item.title) ||
            !!!item.title ||
            item.title == "操作"
        )
        .map((item, index) => {
          if (item.title !== "操作" && item.title) {
            item.titleSort = this.sortTitles.findIndex(
              (sortTitle) => item.title == sortTitle
            );
          } else if (item.title == "操作") {
            item.titleSort = this.sortTitles.length;
          } else {
            item.titleSort = -this.sortTitles.length + index;
          }
          return item;
        });
      currentColumns.sort((a, b) => a.titleSort - b.titleSort);

      currentColumns.forEach(item=>{
        item.width = that.widthTitles[item.title];
      })
      delete currentColumns[currentColumns.length-1].width
      currentColumns[currentColumns.length-1].minWidth= 162;
      this.$emit("on-change", currentColumns);
    },

    reverseSelect() {
      if (this.selectTitles.length > 0) {
        this.selectTitles = [];
      } else {
        this.selectTitles = JSON.parse(JSON.stringify(this.sortTitles));
        this.changeColumns();
      }
    },
  },
  mounted() {
    this.init();
    this.$nextTick(function() {

    this.$on('changeCWidth', function(newWidth, oldWidth, column, event) {
        this.changeColumnsWidth(newWidth, oldWidth, column, event);
      });

});
  },
};
</script>
<style lang="less" scoped>
.filter-columns-btn {
  width: 30px;
  height: 30px;
  line-height: 25px;
  text-align: center;
  border-radius: 2px;
  border: 1px solid #4383f3;
  cursor: pointer;
}
</style>

3.在main.js中注册成全局组件

import FilterColumns from '@/views/my-components/FilterColumns'
Vue.component('filterColumns', FilterColumns);

4.使用方法

在合适位置(一般搜索按钮后,会显示筛选按钮)引入组件

  <filterColumns
              ref="fc"
              :columns="columns"
              @on-change="currentColumns = $event"
            />
  <Table
          @on-column-width-resize="$refs.fc.changeColumnsWidth(arguments)"
        :columns="currentColumns"
        :data="data"
        ref="table"
      ></Table>


<script>
export default {
  data() {
  //可展示的字段
  columns:[
    {
          type: "selection",
          width: 35,
          align: "center",
        },
        {
          type: "index",
          width: 55,
          align: "center",
        },
    ],
    //需要展示的字段,设置为空数组即可
    currentColumns:[],
  }
}
</script>
  • 22
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
iView表格组件是一种基于Vue.js的适用于管理和展示数据的强大工具。它提供了一种嵌套表格的功能,使得我们可以在表格的某一中再次引入一个子表格,并且可以固定某些使其在水平滚动时保持固定位置。 要实现表格嵌套表格固定,我们需要使用iView提供的`fixed`属性。首先,我们可以通过在主表格定义中设置`fixed`属性为left或right来固定。这将使得指定的固定在表格的左侧或右侧位置。 然后,在主表格的某一中,我们可以使用嵌套表格的方式来创建一个子表格。通过在该的slot中使用`<template>`标签,并添加相应的标识,我们可以在该slot中引入子表格。 对于子表格,我们也可以设置任意多个,并通过设置`fixed`属性来决定哪些需要固定。这样,当主表格进行水平滚动时,固定将始终保持在其指定的位置上。 需要注意的是,表格的父子之间的关系是通过唯一的`expand`字段来确定的。通过在主表格定义中加入一个`type=expand`的,我们可以在展开子表格时将数据传递给子表格。然后,子表格将根据传递的数据显示相应的内容。 总之,通过合理地使用iView表格组件提供的`fixed`属性,我们可以实现表格嵌套表格固定的功能。这种功能在需要同时展示父子表格数据并保持固定位置时非常有用。同时,iView的文档和示例也会提供更详细的使用方法和示例代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值