Element-UI
1、封装Select-Tree组件
1.1、代码实现
el-select-tree/index.js
import SelectTree from "./select-tree.vue";
SelectTree.install = function (Vue) {
Vue.component(SelectTree.name, SelectTree);
};
export { SelectTree };
el-select-tree/select-tree.vue
<template>
<el-select
:disabled="disabled"
:size="size"
:clearable="clearable"
:placeholder="placeholder"
:no-data-text="noDataText"
:popper-class="popperClass"
:popper-append-to-body="popperAppendToBody"
:multiple="multiple"
:value="value"
@visible-change="handleVisibleChange"
@remove-tag="handleRemoveTag"
@clear="handleClear"
ref="selectRef"
>
<el-option
v-if="data.length !== 0"
value=""
style="display: none"
></el-option>
<template v-if="value">
<el-option
:value="item[nodeKey]"
:label="item[props?.label ?? 'label']"
style="display: none"
:key="item[nodeKey]"
v-for="item in optionData"
></el-option>
</template>
<el-tree
:node-key="nodeKey"
:props="props"
:data="data"
:highlight-current="highlightCurrent"
:default-expand-all="defaultExpandAll"
:expand-on-click-node="expandOnClickNode"
:check-on-click-node="checkOnClickNode"
:auto-expand-parent="autoExpandParent"
:show-checkbox="showCheckbox"
:check-strictly="checkStrictly"
@check="handleCkeck"
@current-change="handleCurrentChange"
ref="treeRef"
></el-tree>
</el-select>
</template>
<script>
export default {
name: "ElSelectTree",
componentName: "ElSelectTree",
model: {
prop: "value",
event: "update:value",
},
emits: ["update:value", "visible-change", "change"],
props: {
value: {
type: String | Number | Array,
},
data: {
type: Array,
required: true,
default: () => [],
},
disabled: {
type: Boolean,
default: false,
},
multiple: {
type: Boolean,
default: false,
},
size: {
type: "medium" | "small" | "mini",
},
clearable: {
type: Boolean,
default: false,
},
placeholder: {
type: String,
default: "请选择",
},
noDataText: {
type: String,
default: "无数据",
},
popperClass: {
type: String,
},
popperAppendToBody: {
type: Boolean,
default: true,
},
nodeKey: {
type: String,
required: true,
},
props: {
type: Object,
default: () => {},
},
highlightCurrent: {
type: Boolean,
default: false,
},
defaultExpandAll: {
type: Boolean,
default: false,
},
expandOnClickNode: {
type: Boolean,
default: false,
},
checkOnClickNode: {
type: Boolean,
default: false,
},
autoExpandParent: {
type: Boolean,
default: false,
},
checkStrictly: {
type: Boolean,
default: false,
},
},
computed: {
showCheckbox() {
return this.multiple;
},
},
watch: {
value(val) {
if (!this.multiple) {
this.setCurrentNode(val);
} else {
this.setMultipleCurrentNode(val);
}
if (!val) {
return;
}
this.optionData = this.flatteningTreeData.filter((item) => {
return val.includes(item[this.nodeKey]);
});
},
data(val) {
this.flatteningTree(val);
},
},
data() {
return {
flatteningTreeData: [],
optionData: [],
};
},
methods: {
flatteningTree(data) {
data.forEach((item) => {
const children = this.props?.children ?? "children";
if (item[children] && item[children].length) {
this.flatteningTree(item[children]);
} else {
delete item[children];
}
this.flatteningTreeData.push(item);
});
},
handleCkeck(data, { checkedKeys, halfCheckedKeys }) {
if (this.multiple) {
const val = [...checkedKeys, ...halfCheckedKeys];
this.$emit("update:value", val);
this.$emit("change", val);
}
},
handleCurrentChange(data) {
if (!this.multiple) {
this.$emit("update:value", data[this.nodeKey]);
this.$emit("change", data[this.nodeKey]);
this.$refs.selectRef.blur();
}
},
setCurrentNode(val) {
this.$nextTick(() => {
this.$refs.treeRef.setChecked(val);
});
},
setMultipleCurrentNode(data) {
this.$nextTick(() => {
this.$refs.treeRef.setCheckedKeys(data, this.checkStrictly);
});
},
handleVisibleChange(visible) {
if (visible) {
this.multiple
? this.setMultipleCurrentNode(this.value)
: this.setCurrentNode(this.value);
}
this.$emit("visible-change", visible);
},
handleRemoveTag(val) {
val = this.value.filter((item) => item !== val);
this.$emit("update:value", val);
},
handleClear() {
this.$emit("update:value", undefined);
},
},
};
</script>
1.2、食用文档
- 在 main.js 引入
el-select-tree/index.js
- 使用 Vue.use(SelectTree) 挂载组件
import { SelectTree } from '@/components/el-select-tree'
Vue.use(SelectTree)