{"remainingRequest":"D:\\jenkins\\workspace\\bzzgj-fvue\\node_modules\\vue-loader\\lib\\index.js??vue-loader-options!D:\\jenkins\\workspace\\bzzgj-fvue\\src\\components\\myTree\\index.vue?vue&type=script&lang=js&","dependencies":[{"path":"D:\\jenkins\\workspace\\bzzgj-fvue\\src\\components\\myTree\\index.vue","mtime":1691463999649},{"path":"D:\\jenkins\\workspace\\bzzgj-fvue\\node_modules\\babel-loader\\lib\\index.js","mtime":315532800000},{"path":"D:\\jenkins\\workspace\\bzzgj-fvue\\node_modules\\cache-loader\\dist\\cjs.js","mtime":499162500000},{"path":"D:\\jenkins\\workspace\\bzzgj-fvue\\node_modules\\vue-loader\\lib\\index.js","mtime":499162500000}],"contextDependencies":[],"result":["//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\r\nexport default {\r\n name: 'MyTree',\r\n props: {\r\n tree: { // 树形数据源\r\n type: Array,\r\n default: () => []\r\n },\r\n sonOptions: { // 多项子集配置\r\n type: Array,\r\n default: () => [{\r\n childrenkey: 'children',\r\n nameKey: 'name',\r\n idKey: 'id',\r\n disabledKey: 'disabled',\r\n height: '32px'\r\n }]\r\n },\r\n topChild: { // 顶层对象含义\r\n type: String,\r\n default: 'children'\r\n },\r\n treeParams: { // 个性化样式配置\r\n type: Object,\r\n default: () => {\r\n }\r\n },\r\n indent: { // 相邻级节点间的水平缩进,单位为像素\r\n type: Number,\r\n default: 18\r\n },\r\n defaultExpandAll: { // 是否默认展开所有节点\r\n type: Boolean,\r\n default: false\r\n },\r\n foldAll: { // 折叠时关闭所有已经打开的子集,再次打开时需要一级一级打开\r\n type: Boolean,\r\n default: false\r\n },\r\n openSerch: { // 开启搜索\r\n type: Boolean,\r\n default: false\r\n },\r\n treeStyle: { // 自定义样式类名\r\n type: String,\r\n default: ''\r\n }\r\n },\r\n data() {\r\n return {\r\n treeList: [],\r\n initialData: [],\r\n params: {\r\n prefixIcon: './img/prefix-icon.png', // 前置图标\r\n postIcon: './img/post-icon.png', // 后置图标(自动旋转)\r\n disabledIcon: './img/disabled-icon.png', // 禁用图标\r\n border: false\r\n },\r\n serchVal: ''\r\n }\r\n },\r\n watch: {\r\n tree: {\r\n handler(tree) {\r\n this.params = Object.assign(this.params, this.treeParams)\r\n // console.time('数据处理时间:')\r\n // 异步执行避免后续功能出错\r\n setTimeout(() => {\r\n this.initialData = this.flattenTree(tree)\r\n this.treeList = this.deepClone(this.initialData)\r\n // console.timeEnd('数据处理时间:')\r\n this.$emit('is-finished', this.initialData)\r\n }, 0)\r\n },\r\n immediate: true // 初始化执行\r\n }\r\n },\r\n mounted() {\r\n },\r\n methods: {\r\n // 扁平化树形结构\r\n flattenTree(tree = [], rank = 0, parentIds = []) {\r\n const {sonOptions, topChild, defaultExpandAll, flattenTree} = this\r\n\r\n return tree.reduce((concatArr, item) => {\r\n const {\r\n nameKey,\r\n idKey,\r\n disabledKey,\r\n height\r\n } = sonOptions.find(i => {\r\n return i.childrenkey === (item.childrenkey || topChild)\r\n })\r\n let newItem = {\r\n ...item,\r\n name: item[nameKey] || item.name, // 显示文字\r\n id: item[idKey] || item.id, // 唯一标识符\r\n height: height || '32px', // 高度\r\n isShow: defaultExpandAll || rank === 0, // 自身是否显示\r\n showChild: (defaultExpandAll && !item.lastRank) || false, //子级是否展开\r\n childrenkey: item.childrenkey || topChild, // 父级下层级代表\r\n rank, // 层级\r\n lastRank: false, // 是否为最底层\r\n disabled: !!(item[disabledKey] || item.disabled), // 是否禁用\r\n parentIds, // 父级id数组\r\n parentId: parentIds[parentIds.length - 1] || 0 // 父级id\r\n }\r\n // 合并所有类型的子集数组并打上类型标记\r\n let children = sonOptions.map(({childrenkey}) => {\r\n delete newItem[childrenkey] // 删除扁平化数组对象中的所有子集数组\r\n return childrenkey\r\n }).map(childrenkey => {\r\n if (Array.isArray(item[childrenkey]) && item[childrenkey].length) {\r\n return item[childrenkey].map(_item => {\r\n return {childrenkey, ..._item}\r\n })\r\n }\r\n }).filter(item => item).reduce((sonConcat, son) => {\r\n if (Array.isArray(son) && son.length) return sonConcat.concat(son)\r\n }, [])\r\n // 判断是否到达底层\r\n if (Array.isArray(children) && children.length) {\r\n let parents = [...parentIds]\r\n parents.push(item[sonOptions.find(i => i.childrenkey === topChild).idKey])\r\n return concatArr.concat(newItem, flattenTree(children, rank + 1, parents))\r\n } else {\r\n newItem.lastRank = true\r\n return concatArr.concat(newItem)\r\n }\r\n }, [])\r\n },\r\n\r\n //使用递归的方式实现数组、对象的深拷贝\r\n deepClone(obj) {\r\n // 只拷贝对象\r\n if (typeof obj !== 'object') return\r\n // 根据obj的类型判断是新建一个数组还是一个对象\r\n let newObj = obj instanceof Array ? [] : {}\r\n for (let key in obj) {\r\n // 遍历obj,并且判断是obj的属性才拷贝\r\n if (obj.hasOwnProperty(key)) {\r\n // 判断属性值的类型,如果是对象递归调用深拷贝\r\n newObj[key] = typeof obj[key] === 'object' ? this.deepClone(obj[key]) : obj[key]\r\n }\r\n }\r\n return newObj\r\n },\r\n\r\n // 行点击\r\n rowClick(row) {\r\n const {lastRank, id, disabled} = row\r\n const {foldAll} = this\r\n if (disabled) return this.$emit('disabled-item-click', row)\r\n if (lastRank) return this.$emit('tree-item-click', row)\r\n row.showChild = !row.showChild\r\n this.treeList.forEach((item, index, arr) => {\r\n if (!row.showChild) {\r\n // 关闭子集\r\n if (item.parentIds.includes(id)) {\r\n item.isShow = false\r\n // 是否开启关闭折叠所有子集项功能\r\n if (foldAll) {\r\n arr.forEach(({id}) => {\r\n if (item.parentId === id) item.showChild = false\r\n })\r\n }\r\n }\r\n } else {\r\n // 打开子集\r\n const clickItem = arr.find(({id}) => id === item.parentId) || {}\r\n if (item.parentIds.includes(id) && clickItem.showChild) {\r\n item.isShow = true\r\n }\r\n }\r\n })\r\n },\r\n\r\n // 展开所有列表\r\n expandAll() {\r\n this.treeList.forEach((item, index, arr) => {\r\n if (!item.lastRank && !item.disabled) item.showChild = true\r\n item.isShow = true\r\n // 将禁用项的组件的子集关闭\r\n arr.forEach(_item => {\r\n if (item.parentIds.includes(_item.id) && _item.disabled) {\r\n item.isShow = false\r\n item.showChild = false\r\n }\r\n })\r\n })\r\n },\r\n\r\n // 搜索\r\n serch(serchVal) {\r\n this.serchVal.trim()\r\n const {initialData, tree, flattenTree, expandAll} = this\r\n if (!serchVal) {\r\n return this.treeList = flattenTree(tree)\r\n }\r\n const treeList = initialData.filter(({id}) => {\r\n return [...new Set(initialData.filter(({name}) => {\r\n return name.includes(serchVal) || serchVal.includes(name)\r\n }).reduce((concatArr, {parentIds, id, name}) => {\r\n if (Array.isArray(parentIds) && parentIds.length) return concatArr.concat(parentIds, id)\r\n }, []))].includes(id)\r\n })\r\n let max = 0\r\n treeList.map(({rank}) => rank).forEach(item => max = item > max ? item : max)\r\n treeList.forEach(item => {\r\n if (item.rank === max) {\r\n item.showChild = false\r\n item.lastRank = true\r\n }\r\n })\r\n this.treeList = treeList\r\n expandAll()\r\n },\r\n\r\n // 重置搜索内容\r\n reset() {\r\n this.serchVal = ''\r\n this.treeList = this.flattenTree(this.tree)\r\n },\r\n\r\n // 高亮搜索内容\r\n brightenKeyword(val, keyword) {\r\n if (keyword.length) {\r\n let keywordArr = keyword.split('')\r\n val = val + ''\r\n keywordArr.forEach(item => {\r\n if (val.indexOf(item) !== -1 && item !== ' ') {\r\n val = val.replace(\r\n new RegExp(item, 'g'),\r\n '' + item + ''\r\n )\r\n }\r\n })\r\n }\r\n return val\r\n }\r\n }\r\n}\r\n",null]}