Vue若依管理系统-显隐列持久化

本文介绍如何使用Vue和Element UI实现用户显隐列设置的持久化,利用Redis存储用户的列显示偏好,确保用户在不同登录会话间保持一致的列显示状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


关键词:Vue;显隐列持久化,elementUI,若依管理系统

需求

将显隐列持久化到redis中,从而记住该用户隐藏了那些列,重新登录后依然存在。
在这里插入图片描述

主要代码

  • 当前网页
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns.sync="columns"/>
  • “right-toolbar”组件
<template>
  <div class="top-right-btn">
    <el-row>
      <el-tooltip class="item" effect="dark" :content="showSearch ? '隐藏搜索' : '显示搜索'" placement="top"
                  v-if="searchVisible">
        <el-button size="mini" circle icon="el-icon-search" @click="toggleSearch()"/>
      </el-tooltip>
      <el-tooltip class="item" effect="dark" content="刷新" placement="top" v-if="refreshVisible">
        <el-button size="mini" circle icon="el-icon-refresh" @click="refresh()"/>
      </el-tooltip>
      <el-tooltip class="item" effect="dark" :content="sortable ? '禁用排序' : '启用排序'" placement="top" v-if="sortVisible">
        <el-button size="mini" circle icon="el-icon-sort" @click="toggleSortable()"/>
      </el-tooltip>
      <el-tooltip class="item" effect="dark" content="显隐列" placement="top" v-if="columns">
        <el-button size="mini" circle icon="el-icon-menu" @click="showColumn()"/>
      </el-tooltip>
    </el-row>
    <el-dialog :title="title" :visible.sync="open" append-to-body>
      <el-transfer
        :titles="['显示', '隐藏']"
        v-model="value"
        :data="columns"
        @change="dataChange"
      ></el-transfer>
    </el-dialog>
  </div>
</template>

<script>
import {getColumn,uploadColumn} from "../../../api/common/column";

export default {
  name: "RightToolbar",
  data() {
    return {
      // 显隐数据
      value: [],
      // 弹出层标题
      title: "显示/隐藏",
      // 是否显示弹出层
      sortable: true,
      open: false
    }
  },
  props: {
    showSearch: {
      type: Boolean,
      default: true
    },
    columns: {
      type: Array
    },
    searchVisible: {
      type: Boolean,
      default: true
    },
    refreshVisible: {
      type: Boolean,
      default: true
    },
    sortVisible: {
      type: Boolean,
      default: true
    }
  },
  created() {
    // 显隐列初始默认隐藏列
    this.fixColumnLocation();

    /** 2022-6-6,此处用于获取显隐列,并传递到父属性上 */
    getColumn(this.$route.name).then(response => {
      let myColumns = response.data;
      if (response.data === undefined || myColumns.length !== this.columns.length) return;
      this.$emit("update:columns", myColumns);
    });
  },
  methods: {
    // 搜索
    toggleSearch() {
      this.$emit("update:showSearch", !this.showSearch)
    },
    // 刷新
    refresh() {
      this.$emit("queryTable")
    },
    // 排序
    toggleSortable() {
      this.sortable = !this.sortable
      this.$emit("controlSortable", !this.sortable)
    },
    // 右侧列表元素变化
    dataChange(data) {
      for (let item in this.columns) {
        const key = this.columns[item].key
        this.columns[item].visible = !data.includes(key)
      }
      /** 2022-6-1,kxb,显隐列上传 */
      uploadColumn(this.$route.name, this.columns).then();
    },
    // 打开显隐列dialog
    showColumn() {
      this.open = true;
      this.fixColumnLocation();
    },
    /** 2022-6-2,修改初始化页面时隐藏字段在显示字段中的bug,添加该方法至打开dialog  */
    fixColumnLocation(){
      // 显隐列初始默认隐藏列
      for (let item in this.columns) {
        if (this.columns[item].visible === false) {
          this.value.push(parseInt(item))
        }
      }
    },
  },
}
</script>
<style lang="scss" scoped>
::v-deep .el-transfer__button {
  border-radius: 50%;
  padding: 12px;
  display: block;
  margin-left: 0px;
}

::v-deep .el-transfer__button:first-child {
  margin-bottom: 10px;
}
</style>
  • js
import request from '@utils/request'

/** 2022-6-1,获取显隐列的map */
export function getColumn(pageName) {
    return request({
        url: '/invoice/column',
        method: 'get',
        params: {"pageName": pageName}
    })
}
/** 2022-6-1,上传显隐列的map */
export function uploadColumn(pageName, data) {
    return request({
        url: '/invoice/column',
        method: 'post',
        params: {
            pageName: pageName,
        },
        data: data
    })
}

  • controller
@RestController
@RequestMapping("column")
public class ColumnController {
    @Autowired
    private ColumnService columnService;

    @GetMapping
    public AjaxResult getColumn(@RequestParam("pageName") String pageName){
        List<Map> list = columnService.getColumn(pageName, SecurityUtils.getEnterpriseId());
        return AjaxResult.success(list);
    }

    @PostMapping
    public AjaxResult uploadColumn(@RequestParam("pageName") String pageName, @RequestBody List<Map> list){
        Boolean column = columnService.uploadColumn(pageName, SecurityUtils.getEnterpriseId(), list);
        return AjaxResult.success(column);
    }
}
  • service
public interface ColumnService {

    public List<Map> getColumn(String pageName, Long userId);

    public Boolean uploadColumn(String pageName, Long userId, List<Map> list);
}
@Service
public class ColumnServiceImpl implements ColumnService {
    private static final String KEY = "column:";

    @Override
    public List<Map> getColumn(String pageName, Long tenant) {
        return (List<Map>) RedisHashUtils.hGet(KEY + pageName, String.valueOf(tenant));
    }

    @Override
    public Boolean uploadColumn(String pageName, Long tenant, List<Map> list) {
        return RedisHashUtils.hSet(KEY + pageName, String.valueOf(tenant), list);
    }
}
  • 工具类
public class RedisHashUtils {
    private final static RedisService redisService = SpringUtils.getBean(RedisService.class);

    /**
     * 直接以map集合的方式添加key对应的值
     * @param key map中key已经存在,覆盖替换
     * @param map map中key不存在,新增
     * @return
     */
    public static Boolean hmSet(final String key, Map map) {
        boolean result = false;
        try {
            redisService.redisTemplate.opsForHash().putAll(key, map);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 以map集合的方式添加key对应的值,并缓存一天时间
     */
    public static Boolean hmSetExpireOneDay(final String key, Map map) {
        boolean result = false;
        try {
            redisService.redisTemplate.opsForHash().putAll(key, map);
            redisService.redisTemplate.expire(key, 1, TimeUnit.DAYS);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 新增hashMap值
     * @param key   为Redis的key
     * @param mapKey    为key对应的map值的key
     * @param value 为key对应的map值的值
     * @return
     */
    public static Boolean hSet(String key, String mapKey, Object value){
        boolean result = false;
        try {
            redisService.redisTemplate.opsForHash().put(key, mapKey, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 新增hashMap值,并缓存一天时间
     */
    public static Boolean hSetExpireOneDay(String key, String mapKey, Object value){
        boolean result = false;
        try {
            redisService.redisTemplate.opsForHash().put(key, mapKey, value);
            redisService.redisTemplate.expire(key, 86400, TimeUnit.SECONDS);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static Boolean hSetExpireOneMonth(String key, String mapKey, Object value, Long time){
        boolean result = false;
        try {
            redisService.redisTemplate.opsForHash().put(key, mapKey, value);
            redisService.redisTemplate.expire(key, time, TimeUnit.SECONDS);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 以hashMap集合的方式添加key对应的值,并缓存到指定的时间
     */
    public static Boolean hSetExpireCustomize(final String key, String mapKey, Object value, Date date) {
        boolean result = false;
        try {
            redisService.redisTemplate.opsForHash().put(key, mapKey, value);
            redisService.redisTemplate.expireAt(key, date);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 获取hash缓存
     * @param key   redis的key
     * @param filed hash的map的key
     * @return
     */
    public static Object hGet(String key, Object filed) {
        return redisService.redisTemplate.opsForHash().get(key, filed);
    }

    /**
     * 当前key是否存在value
     */
    public static Boolean hExist(String key, String mapName){
        return redisService.redisTemplate.opsForHash().hasKey(key, mapName);
    }

    /**
     * 以集合的方式获取这些键对应的map
     * @param key   redis的key
     * @param list  将hash中的key存到list当中查找
     * @return
     */
    public static List HmultiGet(String key, List list) {
        return redisService.redisTemplate.opsForHash().multiGet(key, list);
    }

    /**
     * 删除整个对应key的redis数据
     */
    public static Boolean DelAll(String key) {
        return redisService.redisTemplate.delete(key);
    }

    /**
     * 删除hash中某个对应key的数据
     * @param key  redis的key
     * @param filed key
     * @return
     */
    public static Long HDelete(String key, Object filed){
        return redisService.redisTemplate.opsForHash().delete(key, filed);
    }

    /**
     * redis的hash自助工具:先判空,有数据就删除,重新写入;否则,直接写入
     * @param key redis的key
     * @param filed 数据的key
     * @param obj 数据的value
     */
    public static void HelpMeSet(String key, Object filed, Object obj){
        if (RedisHashUtils.hExist(key, String.valueOf(filed))) {
            RedisHashUtils.HDelete(key, String.valueOf(filed));
        }
        RedisHashUtils.hSet(key, String.valueOf(filed), obj);
    }
}

详解

  1. 找到页面的“right-toolbar”组件并配置。未改与改过对比:
    添加sync主要用于双向绑定。(修饰符.sync的用法)
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"/>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns.sync="columns"/>

2.在created里面添加一个用于获取 当前用户显隐列字段的 方法

    getColumn(this.$route.name).then(response => {
      let myColumns = response.data;
      if (response.data === undefined || myColumns.length !== this.columns.length) return;
      this.$emit("update:columns", myColumns);
    });
  1. 在dataChange添加上传用户显隐列字段的方法,这里是改变显隐列的时候触发的,用的redis的map来存储的
uploadColumn(this.$route.name, this.columns).then();

在这里插入图片描述
对应redis的信息:
在这里插入图片描述
value存的就是这个:

 columns: [
        {key: 0, label: `序号`, visible: true},
        {key: 1, label: `开票日期`, visible: true},
        {key: 2, label: `发票代码`, visible: true},
        {key: 3, label: `发票号码`, visible: true},
        {key: 4, label: `销方税号`, visible: true},
        {key: 5, label: `发票状态`, visible: true},
        {key: 6, label: `发票类型`, visible: true},
        {key: 7, label: `操作状态`, visible: true},
        {key: 8, label: `机构名称`, visible: true},
        {key: 9, label: `项目名称`, visible: true},
        {key: 10, label: `金额`, visible: true},
        {key: 11, label: `税额`, visible: true},
        {key: 12, label: `是否勾选`, visible: true},
        {key: 13, label: `抵扣额`, visible: true},
        {key: 14, label: `抵扣方式`, visible: true},
        {key: 15, label: `提交时间`, visible: true},
        {key: 16, label: `验收时间`, visible: true},
        {key: 17, label: `认证时间`, visible: true},
        {key: 18, label: `报账单号`, visible: true},
      ],
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值