当前位置: 首页> 教育> 就业 > 使用el-cascader封装一个下拉级联按钮BaseCascadeDropDown

使用el-cascader封装一个下拉级联按钮BaseCascadeDropDown

时间:2025/7/9 11:44:43来源:https://blog.csdn.net/weixin_45549481/article/details/141712220 浏览次数:0次

使用el-pop + el-cascader-panel封装

每次级联树展开时,需要动态计算弹窗的宽度,还不如直接使用el-cascader + el-button进行封装

<template><el-popoverref="popover"placement="bottom"width="200":trigger="trigger"v-model="visible"><el-cascader-panel:options="children"@change="handleCascaderClick":props="cascaderProps"></el-cascader-panel><slot name="button" slot="reference"><el-buttonv-if="children.length":type="buttonConfig.type || 'text'":size="buttonConfig.size"v-permissions="getPermissionCode(buttonConfig)"@click="handleClick(buttonConfig)"v-bind="{ ...buttonConfig }">{{ buttonConfig.btn}}<iclass="el-icon-arrow-down el-icon--right"v-if="!buttonConfig.hideArrow"></i></el-button></slot></el-popover>
</template><script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator'const defaultCascaderProps = {expandTrigger: 'hover',value: 'key',label: 'btn',
}
@Component({name: 'BaseCascadeDropDown' //? 级联下拉按钮
})
export default class extends Vue {@Prop({ default: () => ({}) }) buttonConfig!: any //? 下拉按钮的配置@Prop({ default: () => ({}) }) data?: any //? 下拉按钮的数据,用于动态属性的配置,后面也会将数据传出入@Prop({ default: () => [] }) children: any[] //? 下拉按钮的选项@Prop({ default: 'hover' }) trigger: string //? 气泡的触发方式,,默认悬浮展示@Prop({ default: 'hover' }) expandTrigger: string //? 级联次级菜单的展开方式,默认悬浮展示@Prop({ default: () => defaultCascaderProps }) cascaderProps: any //? 级联的配置选项,次级菜单展开方式,默认悬浮展示//* 事件监听//* eventHandler //? 按钮列的总事件监听hide = falsevisible = falsemounted() {const popoverRef: any = this.$refs.popover// if (!popoverRef.popperElm.children.length) {//   this.hide = true// }}togglePopover() {this.visible = !this.visible;}getPermissionCode(button) { //todo 获取权限码if (typeof button.permissionCode === 'function') {return button.permissionCode(this.data, button.key)}return button.permissionCode}handleClick(button) {this.togglePopover()let loadingInstanceif (button.needLoading) {loadingInstance = this.$loading({lock: button.loadLock || true,text: button.loadText || 'Loading',spinner: button.loadSpinner || 'el-icon-loading',background: 'rgba(0, 0, 0, 0.7)'})}const params = {event: button.key,data: this.data,extraParams: {button,closeLoading: () => {button.needLoading && loadingInstance.close()}}}if (typeof button.submit === 'function') {button.submit(params)}this.handleEventHandler(params)}handleCascaderClick(value) {this.visible = false;const subButtonConfig = this.children.find((subButton) => subButton.key === value) //? 子按钮的配置let loadingInstanceif (subButtonConfig.needLoading) {loadingInstance = this.$loading({lock: subButtonConfig.loadLock || true,text: subButtonConfig.loadText || 'Loading',spinner: subButtonConfig.loadSpinner || 'el-icon-loading',background: 'rgba(0, 0, 0, 0.7)'})}const params = {event: subButtonConfig.key,data: this.data,extraParams: {button: subButtonConfig,subButtonConfig,closeLoading: () => {subButtonConfig.needLoading && loadingInstance.close()}}}if (typeof subButtonConfig.submit === 'function') {subButtonConfig.submit(params)}this.handleEventHandler(params)}needHidden(button) {//todo 是否需要按钮隐藏if (typeof button.hidden === 'function') {return !!button.hidden(this.data, button.key || button.permissionCode)}return button.hidden}needDisabled(button) {//todo 判断是否需要禁用按钮if (typeof button.disabled === 'function') {return button.disabled(this.data, button.key || button.permissionCode)}return button.disabled}handleEventHandler({ event, data, extraParams = {} }) {//todo 调用外部方法this.$emit('eventHandler', {event,data,extraParams})}
}
</script><style lang="scss" scoped></style>

使用el-cascader + el-button进行封装

1、隐藏el-cascader里面的input框;
2、点击按钮时,弹出el-cascader会自动计算宽度的弹窗
3、每次点击(后)需要将勾选状态重置 —— 发现el-cascader组件内部问题,修改其勾选状态不生效,直接修改el-cascader组件内的数据也不生效,只能将其销毁重建

<template><div><el-cascaderref="cascader"v-model="value"v-if="cascaderShow"class="cascader_dropdown":options="children"@change="handleCascaderClick":props="cascaderProps"></el-cascader><slot name="button"><el-buttonv-if="children.length":type="buttonConfig.type || 'text'":size="buttonConfig.size"v-permissions="getPermissionCode(buttonConfig)"@click="handleClick(buttonConfig)"v-bind="{ ...buttonConfig }">{{ buttonConfig.btn }}<iclass="el-icon-arrow-down el-icon--right"v-if="!buttonConfig.hideArrow"></i></el-button></slot></div>
</template><script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator'
import { isBoolean } from 'xe-utils'const defaultCascaderProps = {expandTrigger: 'hover',multiple: false,value: 'key',label: 'btn',children: 'children'
}
@Component({name: 'BaseCascadeDropDown' //? 级联下拉按钮
})
export default class extends Vue {@Prop({ default: () => ({}) }) buttonConfig!: any //? 下拉按钮的配置@Prop({ default: () => ({}) }) data?: any //? 下拉按钮的数据,用于动态属性的配置,后面也会将数据传出入@Prop({ default: () => [] }) children: any[] //? 下拉按钮的选项@Prop({ default: 'hover' }) trigger: string //? 气泡的触发方式,,默认悬浮展示@Prop({ default: 'hover' }) expandTrigger: string //? 级联次级菜单的展开方式,默认悬浮展示@Prop({ default: () => defaultCascaderProps }) cascaderProps: any //? 级联的配置选项,次级菜单展开方式,默认悬浮展示//* 事件监听//* eventHandler //? 按钮列的总事件监听value = []hide = falsevisible = falsecascaderShow = truemounted() {const cascaderRef: any = this.$refs.cascader;// if (!popoverRef.popperElm.children.length) {//   this.hide = true// }}toggleDropDownVisible(visible?) {const cascaderRef: any = this.$refs.cascader;this.visible = isBoolean(visible) ? visible : !this.visible;cascaderRef.toggleDropDownVisible(this.visible)}getPermissionCode(button) { //todo 获取权限码if (typeof button.permissionCode === 'function') {return button.permissionCode(this.data, button.key)}return button.permissionCode}findCurrentItem(valuePath, data) { //todo 根据路径找到对应树形结构中的某个节点const { value, children } = this.cascaderProps;if (Array.isArray(valuePath) && valuePath.length) {const currentItem = data.find(item => item[value] === valuePath[0])valuePath.shift()if (!valuePath.length) { //* 没有下一级//* 找到当前级别的数据return currentItem}return this.findCurrentItem(valuePath, currentItem[children])}}handleClick(button) {this.toggleDropDownVisible()let loadingInstanceif (button.needLoading) {loadingInstance = this.$loading({lock: button.loadLock || true,text: button.loadText || 'Loading',spinner: button.loadSpinner || 'el-icon-loading',background: 'rgba(0, 0, 0, 0.7)'})}const params = {event: button.key,data: this.data,extraParams: {button,closeLoading: () => {button.needLoading && loadingInstance.close()}}}if (typeof button.submit === 'function') {button.submit(params)}this.handleEventHandler(params)}handleCascaderClick(valuePath) {if (Array.isArray(valuePath) && valuePath.length) {const subButtonConfig = this.findCurrentItem(valuePath, this.children)let loadingInstanceif (subButtonConfig.needLoading) {loadingInstance = this.$loading({lock: subButtonConfig.loadLock || true,text: subButtonConfig.loadText || 'Loading',spinner: subButtonConfig.loadSpinner || 'el-icon-loading',background: 'rgba(0, 0, 0, 0.7)'})}const params = {event: subButtonConfig.key,data: this.data,extraParams: {button: subButtonConfig,subButtonConfig,closeLoading: () => {subButtonConfig.needLoading && loadingInstance.close()}}}if (typeof subButtonConfig.submit === 'function') {subButtonConfig.submit(params)}this.handleEventHandler(params)}this.toggleDropDownVisible(false) //* 关闭弹窗this.visible = falsethis.cascaderShow = false; //* 临时将其销毁重建this.$nextTick(() => {this.cascaderShow = true;})}needHidden(button) {//todo 是否需要按钮隐藏if (typeof button.hidden === 'function') {return !!button.hidden(this.data, button.key || button.permissionCode)}return button.hidden}needDisabled(button) {//todo 判断是否需要禁用按钮if (typeof button.disabled === 'function') {return button.disabled(this.data, button.key || button.permissionCode)}return button.disabled}handleEventHandler({ event, data, extraParams = {} }) {//todo 调用外部方法this.$emit('eventHandler', {event,data,extraParams})}
}
</script><style lang="scss" scoped>
::v-deep {.cascader_dropdown {input {display: none;}}// .el-cascader__dropdown {//   .el-cascader-menu {//     min-width: 130px !important;//   }// }
}
</style>
关键字:使用el-cascader封装一个下拉级联按钮BaseCascadeDropDown

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: