记录一次设计一个toolbar的思路

117 阅读1分钟

背景

在做公司的一个管理系统的时候,页面基本都是搜索框,按钮,表格,于是想着封装一下,搞成配置,于是搞了三个组件,一个搜索的form,一个功能的toolbar,一个table,form还能复用到新增删除,toolbar的封装好像没啥用,反正能复用到好几地方,统一了样式,也统一了权限,至于解决什么问题,我也不知道,就想着封装一下,反正用着挺爽。。。

特别说明

这个思路是跟着一位公司一位大佬学的,纯记录一下,侵删!

效果

image.png

封装toolbar

taolar.vue 代码 说明:v-permission 为自定义指令,用做权限控制

<el-row :gutter="10">
  <el-col :span="1.5" v-for="btn in buttons" :key="btn.key">
    <el-dropdown v-if="btn.children && btn.children.length > 0" @command="handleCommand" v-permission="btn.permissions">
      <el-button class="el-dropdown-link" :type="btn.type">
        {{ btn.label }}
        <el-icon class="el-icon--right">
          <arrow-down />
        </el-icon>
      </el-button>
      <template #dropdown>
        <el-dropdown-menu>
          <el-dropdown-item v-for="item in btn.children" :key="item.key" :command="item">
            {{ item.label }}
          </el-dropdown-item>
        </el-dropdown-menu>
      </template>
    </el-dropdown>
    <el-button
      v-else
      :type="btn.type"
      :icon="btn.icon"
      :disabled="btn.disabled"
      @click="handleClick(btn)"
      v-permission="btn.permissions"
      plain
    >
      {{ btn.label }}
    </el-button>
  </el-col>
</el-row>
<script setup name="Toolbar">
const props = defineProps({
    buttons: Array,
})
const handleClick = (action) => {
    emits('action', action)
}
const handleCommand = (action) => {
    emits('action', action)
}
</script>

事件订阅器

每个按钮触发的事件都是不一样的,由具体功能决定。如果每个页面都if判断一下具体哪个按钮,或者switch,不够优雅(狗头狗头),于是:

useSubscribe.js

class FnController {
  constructor() {
    this.fnManager = {}
  }
  subscribe(key, type, fn) {
    if (!this.fnManager[key]) {
      this.fnManager[key] = {}
    }
    if (!this.fnManager[key][type]) {
      this.fnManager[key][type] = []
    }
    this.fnManager[key][type].push(fn)
  }
  dispatch(key, type, ...args) {
    if (this.fnManager[key] && this.fnManager[key][type]) {
      this.fnManager[key][type].forEach((fn) => {
        fn(...args)
      })
    } else {
      console.log(`${key}${type}方法尚未定义,请检查`)
    }
  }
  clearSubcribe() {
    this.fnManager = {}
  }
}

export const useSubscribe = FnController

改造toolbar

<script setup name="Toolbar">
import { useSubscribe } from '@/hooks/useSubscribe'
const props = defineProps({
    buttons: Array,
})
const subscribeInstance = new useSubscribe()
emits('handleActions', {
  subscribe: (key, fn) => {
    subscribeInstance.subscribe(key, 'click', fn)
  },
})
const handleClick = (action) => {
  subscribeInstance.dispatch(action.key, 'click', action)
}
const handleCommand = (action) => {
  subscribeInstance.dispatch(action.key, 'click', action)
}
</script>

使用

index.vue 具体代码如下

<Form />
<Toolbar :buttons="buttons" @handleActions="handleActions" />
<Table />
<script setup name="SearchTable">
const buttons = [
    { key: 'add', label: '新增', icon: 'Plus', type: 'primary', permissions: ['base:school:add'] },
    { key: 'edit', label: '修改', permissions: ['base:school:edit']},
]
// 订阅具体事件
const handleActions = ({ subscribe })=>{
    subscribe('add', (item) => {
	console.log('点击了新增')
    })
    subscribe('edit', (item) => {
	console.log('点击了修改')
    })
}

</script>

结束

每天一个小技巧,从入门到放弃。