| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- <template>
- <el-select ref="treeSelect" :size="size" :value="valueTitle" :clearable="clearable" @clear="clearHandle" :style="{width:width}">
- <el-input :size="size" class="selectInput" :placeholder="placeholder" v-model="filterText"></el-input>
- <el-option :value="valueTitle" :label="valueTitle" class="options">
- <el-tree
- id="tree-option"
- ref="selectTree"
- :accordion="accordion"
- :data="optionData"
- :props="props"
- :node-key="props.value"
- :default-expanded-keys="defaultExpandedKey"
- :filter-node-method="filterNode"
- @node-click="handleNodeClick"
- ></el-tree>
- </el-option>
- </el-select>
- </template>
- <script>
- export default {
- name: "el-tree-select",
- props: {
- /* 配置项 */
- props: {
- type: Object,
- default: () => {
- return {
- value: "id", // ID字段名
- label: "name", // 显示名称
- children: "children" // 子级字段名
- };
- }
- },
- /* 选项列表数据(树形结构的对象数组) */
- options: {
- type: Array,
- default: () => {
- return [];
- }
- },
- /* 初始值 */
- value: {
- type: String,
- default: () => {
- return null;
- }
- },
- /* 初始值 */
- size: {
- type: String,
- default: () => {
- return "small";
- }
- },
- width: {
- type: String,
- default: () => {
- return "200px";
- }
- },
- /* 可清空选项 */
- clearable: {
- type: Boolean,
- default: () => {
- return true;
- }
- },
- /* 自动收起 */
- accordion: {
- type: Boolean,
- default: () => {
- return true;
- }
- },
- placeholder: {
- type: String,
- default: () => {
- return "检索关键字";
- }
- }
- },
- computed: {
- /* 转树形数据 */
- optionData() {
- //第一个节点为根节点
- if (this.options.length > 0) {
- var rootId = this.options[0].id;
- let cloneData = JSON.parse(JSON.stringify(this.options)); // 对源数据深度克隆
- return cloneData.filter(father => {
- // 循环所有项,并添加children属性
- let branchArr = cloneData.filter(
- child => father.id == child.parentId
- ); // 返回每一项的子级数组
- branchArr.length > 0 ? (father.children = branchArr) : ""; //给父级添加一个children属性,并赋值
- return father.id == rootId || father.parentId == null; //返回第一层
- });
- } else {
- return [];
- }
- }
- },
- data() {
- return {
- filterText: "",
- valueId: this.value, // 初始值
- valueTitle: "",
- defaultExpandedKey: []
- };
- },
- mounted() {
- this.initHandle();
- },
- methods: {
- // 初始化值
- initHandle() {
- console.log("options.length=" + this.options.length);
- console.log(this.value);
- var arr = this.options.filter(item=>item.id == this.value);
- if(arr.length>0){
- this.valueTitle = arr[0][this.props.label];
- }
- if(this.valueId){
- this.$refs.selectTree.setCurrentKey(this.valueId); // 设置默认选中
- this.defaultExpandedKey = [this.valueId]; // 设置默认展开
- }
- this.initScroll();
- },
- // 初始化滚动条
- initScroll() {
- this.$nextTick(() => {
- let scrollWrap = document.querySelectorAll(
- ".el-scrollbar .el-select-dropdown__wrap"
- )[0];
- let scrollBar = document.querySelectorAll(
- ".el-scrollbar .el-scrollbar__bar"
- );
- scrollWrap.style.cssText =
- "margin: 0px; max-height: none; overflow: hidden;";
- scrollBar.forEach(ele => (ele.style.width = 0));
- });
- },
- // 切换选项
- handleNodeClick(node) {
- this.valueTitle = node[this.props.label];
- this.valueId = node[this.props.value];
- //this.node = node;
- this.$emit("input", this.valueId);
- this.$refs.treeSelect.blur();
- //this.$emit('getValue',node)
- this.defaultExpandedKey = [];
- },
- // 清除选中
- clearHandle() {
- this.valueTitle = "";
- this.valueId = null;
- this.defaultExpandedKey = [];
- this.clearSelected();
- this.$emit("input", null);
- },
- /* 清空选中样式 */
- clearSelected() {
- let allNode = document.querySelectorAll("#tree-option .el-tree-node");
- allNode.forEach(element => element.classList.remove("is-current"));
- },
- filterNode(value, data) {
- if (!value) return true;
- return data.name.indexOf(value) !== -1;
- }
- },
- watch: {
- value(newVal,oldVal) {
- this.valueId = newVal;
- if(newVal=='') {
- this.clearHandle();
- }
- this.initHandle();
- },
- options(newVal,oldVal) {
- //如果options读取慢,则
- if(oldVal==null || oldVal.length==0){
- setTimeout(()=>{
- this.initHandle();
- },100);
- }
- },
- filterText(val) {
- this.$refs.selectTree.filter(val);
- }
- }
- };
- </script>
- <style>
- .el-scrollbar .el-scrollbar__view .el-select-dropdown__item {
- height: auto;
- max-height: 274px;
- padding: 0;
- overflow: hidden;
- overflow-y: auto;
- }
- .el-select-dropdown__item.selected {
- font-weight: normal;
- }
- ul li >>> .el-tree .el-tree-node__content {
- height: auto;
- padding: 0 20px;
- }
- .el-tree-node__label {
- font-weight: normal;
- }
- .el-tree >>> .is-current .el-tree-node__label {
- color: #409eff;
- font-weight: 700;
- }
- .el-tree >>> .is-current .el-tree-node__children .el-tree-node__label {
- color: #606266;
- font-weight: normal;
- }
- .selectInput {
- padding: 0 5px;
- box-sizing: border-box;
- }
- </style>
|