fuyongxin
2026-06-03 00e0dbbf98347b1e47a7e0aedd41baa61f7567ed
ruoyi-ui/src/components/RightToolbar/index.vue
@@ -38,6 +38,8 @@
</template>
<script>
import cache from '@/plugins/cache'
export default {
  name: "RightToolbar",
  data() {
@@ -76,6 +78,11 @@
      type: Number,
      default: 10
    },
    /* 列显隐状态记忆的 localStorage key(传入则启用记忆,不传则不记忆) */
    storageKey: {
      type: String,
      default: ""
    }
  },
  computed: {
    style() {
@@ -103,6 +110,23 @@
    }
  },
  created() {
    // 如果传入了 storageKey,从 localStorage 恢复列显隐状态
    if (this.storageKey) {
      try {
        const saved = cache.local.getJSON(this.storageKey)
        if (saved && typeof saved === 'object') {
          if (Array.isArray(this.columns)) {
            this.columns.forEach((col, index) => {
              if (saved[index] !== undefined) col.visible = saved[index]
            })
          } else {
            Object.keys(this.columns).forEach(key => {
              if (saved[key] !== undefined) this.columns[key].visible = saved[key]
            })
          }
        }
      } catch (e) {}
    }
    if (this.showColumnsType == 'transfer') {
      // transfer穿梭显隐列初始默认隐藏列
      if (Array.isArray(this.columns)) {
@@ -123,7 +147,34 @@
  methods: {
    // 搜索
    toggleSearch() {
      this.$emit("update:showSearch", !this.showSearch)
      let el = this.$el
      let formEl = null
      while ((el = el.parentElement) && el !== document.body) {
        if ((formEl = el.querySelector('.el-form'))) break
      }
      if (!formEl) return this.$emit('update:showSearch', !this.showSearch)
      this._animateSearch(formEl, this.showSearch)
    },
    // 搜索栏动画
    _animateSearch(el, isHide) {
      const DURATION = 260
      const TRANSITION = 'max-height 0.25s ease, opacity 0.2s ease'
      const clear = () => Object.assign(el.style, { transition: '', maxHeight: '', opacity: '', overflow: '' })
      Object.assign(el.style, { overflow: 'hidden', transition: '' })
      if (isHide) {
        Object.assign(el.style, { maxHeight: el.scrollHeight + 'px', opacity: '1', transition: TRANSITION })
        requestAnimationFrame(() => Object.assign(el.style, { maxHeight: '0', opacity: '0' }))
        setTimeout(() => { this.$emit('update:showSearch', false); clear() }, DURATION)
      } else {
        this.$emit('update:showSearch', true)
        this.$nextTick(() => {
          Object.assign(el.style, { maxHeight: '0', opacity: '0' })
          requestAnimationFrame(() => requestAnimationFrame(() => {
            Object.assign(el.style, { transition: TRANSITION, maxHeight: el.scrollHeight + 'px', opacity: '1' })
          }))
          setTimeout(clear, DURATION)
        })
      }
    },
    // 刷新
    refresh() {
@@ -141,6 +192,7 @@
          this.columns[key].visible = !data.includes(index)
        })
      }
      this.saveStorage()
    },
    // 打开显隐列dialog
    showColumn() {
@@ -153,6 +205,7 @@
      } else {
        this.columns[key].visible = event
      }
      this.saveStorage()
    },
    // 切换全选/反选
    toggleCheckAll() {
@@ -162,6 +215,20 @@
      } else {
        Object.values(this.columns).forEach((col) => (col.visible = newValue))
      }
      this.saveStorage()
    },
    // 将当前列显隐状态持久化到 localStorage
    saveStorage() {
      if (!this.storageKey) return
      try {
        let state = {}
        if (Array.isArray(this.columns)) {
          this.columns.forEach((col, index) => { state[index] = col.visible })
        } else {
          Object.keys(this.columns).forEach(key => { state[key] = this.columns[key].visible })
        }
        cache.local.setJSON(this.storageKey, state)
      } catch (e) {}
    }
  },
}