当前位置: 首页 > news >正文

uniapp实现目录树效果,异步加载数据

uniapp目录树

  • 父组件调用目录树组件
<DaTreeVue2:data="treeData":field="{label: 'name',key: 'id',}"@change="handleTreeChange":defaultCheckedKeys="addressDefaultCheckedKey":defaultExpandedKeys="addressDefaultCheckedKey":loadApi="getTreeData"ref="addressRef"loadMode
/>
  • 父组件方法
handleTreeChange(allSelectedKeys, currentItem, parentKeys) {this.addressDefaultCheckedKey = parentKeys;
}// 获取树async getTreeData(code) {let result = {};await this.$u.api.jobPost.getseekTreeData({parentCode: code,}).then((res) => {result = res.map((it) => {if (it.isParent) {it.children = [];return it;} else {return it;}});});return result;}
  • 子组件 
<template><view class="da-tree" :style="{'--theme-color': themeColor}"><scroll-view class="da-tree-scroll" :scroll-y="true" :scroll-x="false"><view class="da-tree-item" :class="{'is-show': item.show}":style="{paddingLeft: item.level * indent + 'rpx'}" v-for="item in datalist" :key="item.key"><view v-if="item.showArrow" class="da-tree-item__icon" @click="handleExpandedChange(item)"><view :class="['da-tree-item__icon--arr','is-loading']" v-if="loadLoading && item.loading" /><view :class="['da-tree-item__icon--arr','is-expand', {'is-right':!item.expand}]" v-else /></view><view v-else class="da-tree-item__icon" /><view class="da-tree-item__checkbox":class="[`da-tree-item__checkbox--${checkboxPlacement}`,{'is--disabled': item.disabled}]"v-if="showCheckbox" @click="handleCheckChange(item)"><view class="da-tree-item__checkbox--icon da-tree-checkbox-checked"v-if="item.checkedStatus === isCheckedStatus" /><view class="da-tree-item__checkbox--icon da-tree-checkbox-indeterminate"v-else-if="item.checkedStatus === halfCheckedStatus" /><view class="da-tree-item__checkbox--icon da-tree-checkbox-outline" v-else /></view><view class="da-tree-item__checkbox":class="[`da-tree-item__checkbox--${checkboxPlacement}`,{'is--disabled': item.disabled}]"v-if="!showCheckbox && showRadioIcon" @click="handleRadioChange(item)"><view class="da-tree-item__checkbox--icon da-tree-radio-checked"v-if="item.checkedStatus === isCheckedStatus" /><view class="da-tree-item__checkbox--icon da-tree-radio-indeterminate"v-else-if="item.checkedStatus === halfCheckedStatus" /><view class="da-tree-item__checkbox--icon da-tree-radio-outline" v-else /></view><view class="da-tree-item__label" :class="'da-tree-item__label--'+item.checkedStatus"@click="handleLabelClick(item)">{{ item.label }} <text class="da-tree-item__label--append"v-if="item.append">{{ item.append }}</text></view></view></scroll-view></view>
</template><script>import {unCheckedStatus,halfCheckedStatus,isCheckedStatus,deepClone,getAllNodeKeys,getAllNodes} from './utils'export default {name: 'DaTree',props: {/*** 树的数据*/data: {type: Array,default: () => [],},/*** 主题色*/themeColor: {type: String,default: '#007aff',},/*** 默认选中的节点,注意单选时为单个key,多选时为key的数组*/defaultCheckedKeys: {type: [Array, String, Number],default: null,},/*** 选择框的位置,可选 left/right*/checkboxPlacement: {type: String,default: 'left',},/*** 是否默认展开全部*/defaultExpandAll: {type: Boolean,default: false,},/*** 默认展开的节点*/defaultExpandedKeys: {type: Array,default: null,},/*** 子项缩进距离,默认40,单位rpx*/indent: {type: Number,default: 40,},/*** 字段对应内容,默认为 {label: 'label',key: 'key', children: 'children', disabled: 'disabled', append: 'append'}*/field: {type: Object,default: null,},/*** 是否开启多选,默认单选*/showCheckbox: {type: Boolean,default: false,},/*** 是否显示单选图标,默认显示*/showRadioIcon: {type: Boolean,default: true,},/*** 单选时只允许选中末级,默认可随意选中*/onlyRadioLeaf: {type: Boolean,default: false,},/*** 多选时,是否执行父子不关联的任意勾选,默认父子关联*/checkStrictly: {type: Boolean,default: false,},/*** 为 true 时,空的 children 数组会显示展开图标*/loadMode: {type: Boolean,default: false,},/*** 异步加载接口*/loadApi: {type: Function,default: null,},/*** 是否渲染禁用值*/checkedDisabled: {type: Boolean,default: false,},/*** 是否返回已禁用的但已选中的key*/packDisabledkey: {type: Boolean,default: true,},/*** 选择时是否展开当前已选的所有下级节点,默认不展开*/expandChecked: {type: Boolean,default: false,},},data() {return {unCheckedStatus,halfCheckedStatus,isCheckedStatus,/** 原始的树数据 */dataRef: [],/** 处理后的一维树项数据 */datalist: [],/** 处理后的以key为键值的树项数据 */datamap: {},/** 默认的展开数据 */expandedKeys: [],/** 默认的已选数据 */checkedKeys: null,/** 加载状态 */loadLoading: false,}},watch: {defaultExpandedKeys: {// deep: true,immediate: true,handler: function(v) {if (v?.length) {this.expandedKeys = v} else {this.expandedKeys = []}// if (v) this.checkInitData(this.datalist)},},defaultCheckedKeys: {// deep: true,immediate: true,handler: function(v) {if (this.showCheckbox) {if (v?.length) {this.checkedKeys = v} else {this.checkedKeys = []}} else {if (v || v === 0) {this.checkedKeys = v} else {this.checkedKeys = null}}// this.checkInitData(this.datalist)},},data: {deep: true,immediate: true,handler: function(v) {this.dataRef = deepClone(v)setTimeout(() => {this.initData()}, 36)},},},methods: {/*** 初始化数据结构*/initData() {const data = deepClone(this.dataRef)this.datalist = []this.datamap = {}// clean treethis.handleTreeData(data)// flat treethis.datalist = this.checkInitData(this.datalist)// console.log('init datalist', this.datalist)// console.log('init datamap', this.datamap)},/*** 转换为节点数据* @param data* @param parent* @param level*/handleTreeData(data = [], parent = null, level = 0, insertIndex = -1, secondIndex) {return data.reduce((prev, cur, index) => {const key = cur[this.field?.key || 'key']const children = cur[this.field?.children || 'children'] || nullconst newItem = this.createNewItem(cur, index, parent, level)this.datamap[key] = newItemif (insertIndex > -1) {this.datalist.splice(insertIndex + 1, 0, newItem)parent.children.push(newItem)if (newItem.parentKeys?.length) {newItem.parentKeys.forEach(k => {this.datamap[k].childrenKeys = [...this.datamap[k].childrenKeys,newItem.key]})}} else {this.datalist.push(newItem)}const hasChildren = children && children.length > 0if (hasChildren) {const childrenData = this.handleTreeData(children, newItem, level + 1)newItem.children = childrenDataconst childrenKeys = childrenData.reduce((p, k) => {const keys = k.childrenKeysp.push(...keys, k.key)return p}, [])newItem.childrenKeys = childrenKeys}newItem.positionCode = cur.positionCode// newItem.parentCodes = cur.parentCodes.split(',')prev.push(newItem)return prev}, [])},/*** 创建节点* @param item* @param index* @param parent* @param level*/createNewItem(item, index, parent, level) {const key = item[this.field?.key || 'key']const label = item[this.field?.label || 'label']const children = item[this.field?.children || 'children'] || nullconst append = item[this.field?.append || 'append'] || nulllet disabled = item[this.field?.disabled || 'disabled'] || falseconst hasChildren = children && children.length > 0const hasEmptyChildren = children && children.length === 0let showArrow = truelet isLeaf = !hasChildrenlet expand = this.defaultExpandAllif (this.loadMode && hasEmptyChildren) {isLeaf = falseexpand = falseshowArrow = true}if (disabled) {showArrow = false}if (hasChildren) {showArrow = true} else {if (this.loadMode && hasEmptyChildren && !disabled) {showArrow = true} else {showArrow = false}}if (!isLeaf && !this.showCheckbox && this.onlyRadioLeaf) {disabled = trueshowArrow = true}const parentKey = parent ? parent.key : nullconst show = this.defaultExpandAll ? true : level === 0const newItem = {key,parentKey,label,append,isLeaf,showArrow,level,expand,show,disabled,loading: false,indexs: [index],checkedStatus: unCheckedStatus,parentKeys: [],childrenKeys: [],children: [],originItem: item,}if (parent) {newItem.parentKeys = [parent.key, ...parent.parentKeys]newItem.indexs = [...parent.indexs, index]}return newItem},/*** 处理初始化内容* @param list*/checkInitData(list) {let checkedKeyList = nulllet expandedKeyList = []if (this.showCheckbox) {checkedKeyList = [...new Set(this.checkedKeys || [])]} else {checkedKeyList = this.checkedKeys || null}this.handleCheckState(list, checkedKeyList)// 处理初始展开expandedKeyList = [...new Set(this.expandedKeys || [])]if (!this.defaultExpandAll) {this.handleExpandState(list, expandedKeyList, true)}return list},/*** 处理选中* @param list* @param checkedKeyList*/handleCheckState(list, checkedKeyList, checked = true) {if (this.showCheckbox) {for (let i = 0; i < list.length; i++) {const item = list[i]if (checkedKeyList?.includes(item.key)) {if (this.checkedDisabled || !item.disabled) {this.handleExpandParentNode(item, checked)this.checkTheChecked(item, checked)}}}} else {// 单选for (let i = 0; i < list.length; i++) {const item = list[i]if (item.key === checkedKeyList && !item.disabled) {if (this.checkedDisabled || !item.disabled) {this.checkTheRadio(item, checked)break}}}}},/*** 校验多选节点* @param item* @param checked*/checkTheChecked(item, checked = true) {const {childrenKeys,parentKeys,disabled = false} = itemif (!this.checkedDisabled && disabled) return// 当前item.checkedStatus = checked ? isCheckedStatus : unCheckedStatusif (!this.checkStrictly) {// 子类childrenKeys.forEach(k => {const childrenItem = this.datamap[k]childrenItem.checkedStatus = (!this.checkedDisabled && childrenItem.disabled) ?childrenItem.checkedStatus : item.checkedStatus})// 父类parentKeys.forEach(k => {const parentItem = this.datamap[k]parentItem.checkedStatus = this.getParentCheckedStatus(parentItem)})}},/*** 校验单选节点* @param item*/checkTheRadio(item, checked) {// console.log('item',item);// console.log('checked',checked);const {parentKeys,isLeaf,disabled = false} = itemif (!this.checkedDisabled && disabled) return// 限制末节点选中,但当前非末节点if (this.onlyRadioLeaf && !isLeaf) {console.error(`DaTree: 限制了末节点选中,当前[${item.label}]非末节点`)return}if (this.datalist?.length) {for (let i = 0; i < this.datalist.length; i++) {const k = this.datalist[i]k.checkedStatus = unCheckedStatus}}parentKeys.forEach(k => {const parentItem = this.datamap[k]parentItem.checkedStatus = this.getParentCheckedStatus(parentItem, checked)})// 当前if (checked === true) {item.checkedStatus = isCheckedStatus}if (checked === false) {item.checkedStatus = unCheckedStatus}// item.checkedStatus = unCheckedStatus  },/*** 处理父节点展开* @param item* @param expand*/handleExpandParentNode(item, expand = true) {if (!expand) returnif (item?.parentKeys?.length) {item.parentKeys.forEach(pk => {if (!this.datamap[pk].expand) {this.datamap[pk].expand = true}})}},/*** 处理节点展开* @param list* @param expandedKeyList* @param expand*/handleExpandState(list, expandedKeyList, expand = true) {for (let i = 0; i < list.length; i++) {const item = list[i]if (expand === true) {// 处理展开if (expandedKeyList?.includes(item.key)) {item.expand = truethis.handleExpandParentNode(item, true)}} else {// 处理收起if (expandedKeyList?.includes(item.key)) {item.expand = falseif (item?.childrenKeys?.length) {item.childrenKeys.forEach(ck => {this.datamap[ck].expand = falsethis.datamap[ck].show = false})}}}}for (let i = 0; i < list.length; i++) {const item = list[i]if (item.level > 0) {const parentItem = this.datamap[item.parentKey]if (parentItem) {if (parentItem.expand && parentItem.show) {item.show = true}}}}},/*** 点击选框* @param item*/handleCheckChange(item) {const {childrenKeys,parentKeys,checkedStatus,isLeaf,originItem = null,disabled = false} = itemif (!this.showCheckbox) returnif (disabled) return// 当前item.checkedStatus = checkedStatus === isCheckedStatus ? unCheckedStatus : isCheckedStatus// 子类if (!this.checkStrictly) {if (this.expandChecked) {item.show = trueitem.expand = childrenKeys?.length > 0 || isLeaf}childrenKeys.forEach(k => {const childrenItem = this.datamap[k]childrenItem.checkedStatus = childrenItem.disabled ? childrenItem.checkedStatus : item.checkedStatusif (this.expandChecked) {childrenItem.show = truechildrenItem.expand = childrenItem?.childrenKeys?.length > 0 || childrenItem.isLeaf}})} else {if (this.expandChecked) {console.error(`DaTree: 多选时,当 checkStrictly 为 true 时,不支持选择自动展开子节点属性(expandChecked)`)}}// 父类if (!this.checkStrictly) {parentKeys.forEach(k => {const parentItem = this.datamap[k]parentItem.checkedStatus = this.getParentCheckedStatus(parentItem)})}const hasCheckedKeys = []for (let i = 0; i < this.datalist.length; i++) {const k = this.datalist[i]if (k.checkedStatus === isCheckedStatus) {if ((this.packDisabledkey && k.disabled) || !k.disabled) {hasCheckedKeys.push(k.key)}}}this.checkedKeys = [...hasCheckedKeys]this.$emit('change', hasCheckedKeys, originItem)},/*** 点击单选* @param item*/handleRadioChange(item) {const {parentKeys,checkedStatus,key,originItem = null,disabled = false} = itemif (this.showCheckbox) returnif (this.onlyRadioLeaf) {this.handleExpandedChange(item)}if (disabled) return// 重置所有选择if (this.datalist?.length) {for (let i = 0; i < this.datalist.length; i++) {const k = this.datalist[i]k.checkedStatus = unCheckedStatus}}parentKeys.forEach(k => {const parentItem = this.datamap[k]parentItem.checkedStatus = this.getParentCheckedStatus(parentItem)})// 当前item.checkedStatus = checkedStatus === isCheckedStatus ? unCheckedStatus : isCheckedStatusthis.checkedKeys = keythis.$emit('change', key, originItem, parentKeys)},/*** 点击标签*/handleLabelClick(item) {if (this.showCheckbox) {this.handleCheckChange(item)} else {this.handleRadioChange(item)}},/*** 点击展开收起* @param item*/async handleExpandedChange(item) {const {expand,originItem = null,loading = false} = itemif (this.loadLoading && loading) returnthis.checkExpandedChange(item)// 异步item.expand = !expandlet currentItem = nullif (!this.showCheckbox && this.onlyRadioLeaf && this.loadMode) {console.error(`DaTree: 单选时,当 onlyRadioLeaf 为 true 时不支持动态数据`)} else {currentItem = await this.loadExpandNode(item)}this.$emit('expand', item, !expand, currentItem || originItem || null)},/*** 检查展开状态* @param item*/checkExpandedChange(item) {const {expand,childrenKeys,children = null} = itemif (expand) {if (childrenKeys?.length) {childrenKeys.forEach(k => {if (this.datamap[k]) {this.datamap[k].show = falsethis.datamap[k].expand = false}})}} else {if (children?.length) {const childrenKeys = children.map(k => k.key)childrenKeys.forEach(k => {if (this.datamap[k]) {this.datamap[k].show = true}})}}},/*** 加载异步数据* @param item*/async loadExpandNode(item) {const {expand,key,children = null} = itemif (expand && this.loadMode && (!children || children.length === 0)) {if (typeof this.loadApi === 'function') {this.expandedKeys.push(key)this.loadLoading = trueitem.loading = trueconst currentNode = deepClone(item)const apiRes = await this.loadApi(currentNode.positionCode)item.originItem = apiRes || nullif (apiRes?.length) {const insertIndex = this.datalist.findIndex(k => k.key === item.key)this.handleTreeData(apiRes, item, item.level + 1, insertIndex)this.datalist = this.checkInitData(this.datalist)} else {// 加载后无数据就移除展开图标item.expand = falseitem.isLeaf = trueitem.showArrow = false}this.loadLoading = falseitem.loading = false}} else {const eki = this.expandedKeys.findIndex(k => k === key)if (eki >= 0) {this.expandedKeys.splice(eki, 1)}}return item},/*** 获取父类的选中状态* @param item*/getParentCheckedStatus(item, checked = true) {console.log(item);console.log(checked);if (!item) {return unCheckedStatus}if (!this.checkedDisabled && item.disabled) {return item.checkedStatus || unCheckedStatus}// 单选时,父类永远为半选// checked为false  unCheckedStatus取消选择if (!this.showCheckbox && checked == true) {// console.log('半半');return halfCheckedStatus}if (!this.showCheckbox && checked === false) {// console.log('add');return unCheckedStatus}const {children} = item// 子类全选中const childrenCheckedAll = children.every(k => k.checkedStatus === isCheckedStatus)if (childrenCheckedAll) {return isCheckedStatus}// 子类全不选中const childrenUncheckedAll = children.every(k => k.checkedStatus === unCheckedStatus)if (childrenUncheckedAll) {return unCheckedStatus}return halfCheckedStatus},/*** 返回已选的 key*/getCheckedKeys() {return getAllNodeKeys(this.datalist, 'checkedStatus', isCheckedStatus, this.packDisabledkey)},/*** 根据key设置已选* @param keys 多选时为key的数组,单选时为key* @param checked 多选时为key的数组,单选时为key*/setCheckedKeys(keys, checked = true) {// console.log('--==========================',keys);// console.log('--==========================',checked);if (!Array.isArray(keys) && this.showCheckbox) {console.error('DaTree: setCheckedKeys 第一个参数非数组,传入的是:', keys)return}const list = this.datalistif (checked === false) {// console.log('11111111111111111111111111111111111111111111111111111111111111111111111');let newCheckedKeysif (this.showCheckbox) {newCheckedKeys = []for (let i = 0; i < this.checkedKeys.length; i++) {const ck = this.checkedKeys[i]if (!keys.includes(ck)) {newCheckedKeys.push(ck)}}newCheckedKeys = [...new Set(newCheckedKeys)]} else {// 单选时,必须至少勾选一个,所以单选不支持取消选中。// newCheckedKeys = nullnewCheckedKeys = keys}this.checkedKeys = newCheckedKeys// console.log(this.checkedKeys);console.log(list);this.handleCheckState(list, keys, false)} else {this.handleCheckState(list, keys, true)if (this.showCheckbox) {this.checkedKeys = [...new Set([...(this.checkedKeys || []), ...(keys || [])])]this.handleExpandState(list, keys, true)} else {// 单选时如果为数组则拿第一个if (Array.isArray(keys)) {keys = keys[0]}this.checkedKeys = keys || nullthis.handleExpandState(list, [keys], true)}}},/*** 返回半选的 key*/getHalfCheckedKeys() {return getAllNodeKeys(this.datalist, 'checkedStatus', halfCheckedStatus, this.packDisabledkey)},/*** 返回已展开的 key*/getExpandedKeys() {return getAllNodeKeys(this.datalist, 'expand', true)},/*** 根据key展开/收起* @param keys key的数组* @param expand true为展开/false为收起*/setExpandedKeys(keys, expand = true) {if (!Array.isArray(keys)) {console.error('DaTree: setExpandedKeys 第一个参数非数组,传入的是:', keys)return}const list = this.datalistif (expand === false) {const newExpandedKeys = []for (let i = 0; i < this.expandedKeys.length; i++) {const ek = this.expandedKeys[i]if (!keys.includes(ek)) {newExpandedKeys.push(ek)}}this.expandedKeys = [...new Set(newExpandedKeys)]this.handleExpandState(list, keys, false)} else {this.datalist.forEach(k => {if (keys.includes(k.key)) {if (k.parentKeys?.length) {k.parentKeys.forEach(pk => {const parentItem = this.datamap[pk]parentItem.expand = trueparentItem.show = trueif (parentItem.children?.length) {const pkcs = parentItem.children.map(k => k.key)pkcs.forEach(pkc => {this.datamap[pkc].show = true})}})}k.show = truethis.handleExpandedChange(k)}})}},/*** 返回已选的节点*/getCheckedNodes() {return getAllNodes(this.datalist, 'checkedStatus', isCheckedStatus, this.packDisabledkey)},/*** 返回半选的节点*/getHalfCheckedNodes() {return getAllNodes(this.datalist, 'checkedStatus', halfCheckedStatus, this.packDisabledkey)},/*** 返回已展开的节点*/getExpandedNodes() {return getAllNodes(this.datalist, 'expand', true)},},}
</script><style lang="scss" scoped>@font-face {font-family: 'iconfont';/* Project id  */src: url('data:application/octet-stream;base64,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') format('truetype');}.da-tree {width: 100%;height: 100%;&-scroll {width: 100%;height: 100%;}&-item {display: flex;align-items: center;height: 0;padding: 0;overflow: hidden;font-size: 28rpx;line-height: 1;visibility: hidden;opacity: 0;transition: opacity 0.2s linear;&.is-show {height: auto;padding: 12rpx 24rpx;visibility: visible;opacity: 1;}&__icon {display: flex;align-items: center;justify-content: center;width: 40rpx;height: 40rpx;overflow: hidden;&--arr {position: relative;display: flex;align-items: center;justify-content: center;width: 32rpx;height: 32rpx;&::after {position: relative;z-index: 1;overflow: hidden;/* stylelint-disable-next-line font-family-no-missing-generic-family-keyword */font-family: 'iconfont' !important;font-size: 32rpx;font-style: normal;color: #999;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;}&.is-expand {&::after {content: '\e604';}}&.is-right {transform: rotate(-90deg);}&.is-loading {animation: IconLoading 1s linear 0s infinite;&::after {content: '\e7f1';}}}}&__checkbox {width: 40rpx;height: 40rpx;overflow: hidden;&--left {order: 0;}&--right {order: 1;}&--icon {position: relative;display: flex;align-items: center;justify-content: center;width: 40rpx;height: 40rpx;&::after {position: relative;top: 0;left: 0;z-index: 1;overflow: hidden;/* stylelint-disable-next-line font-family-no-missing-generic-family-keyword */font-family: 'iconfont' !important;font-size: 32rpx;font-style: normal;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;}&.da-tree-checkbox-outline::after {color: #bbb;content: '\ead5';}&.da-tree-checkbox-checked::after {color: var(--theme-color, #007aff);content: '\ead4';}&.da-tree-checkbox-indeterminate::after {color: var(--theme-color, #007aff);content: '\ebce';}&.da-tree-radio-outline::after {color: #bbb;content: '\ecc5';}&.da-tree-radio-checked::after {color: var(--theme-color, #007aff);content: '\ecc4';}&.da-tree-radio-indeterminate::after {color: var(--theme-color, #007aff);content: '\ea4f';}}&.is--disabled {cursor: not-allowed;opacity: 0.35;}}&__label {flex: 1;margin-left: 4rpx;color: #555;&--2 {color: var(--theme-color, #007aff);}&--append {font-size: 60%;opacity: 0.6;}}}}@keyframes IconLoading {0% {transform: rotate(0deg);}100% {transform: rotate(360deg);}}
</style>
  • utils.js文件
// @ts-nocheck
/** 未选 */
export const unCheckedStatus = 0
/** 半选 */
export const halfCheckedStatus = 1
/** 选中 */
export const isCheckedStatus = 2/*** 深拷贝内容* @param originData 拷贝对象* @author crlang(https://crlang.com)*/
export function deepClone(originData) {const type = Object.prototype.toString.call(originData)let dataif (type === '[object Array]') {data = []for (let i = 0; i < originData.length; i++) {data.push(deepClone(originData[i]))}} else if (type === '[object Object]') {data = {}for (const prop in originData) {// eslint-disable-next-line no-prototype-builtinsif (originData.hasOwnProperty(prop)) { // 非继承属性data[prop] = deepClone(originData[prop])}}} else {data = originData}return data
}/*** 获取所有指定的节点* @param type* @param value* @author crlang(https://crlang.com)*/
export function getAllNodes(list, type, value, packDisabledkey = true) {if (!list || list.length === 0) {return []}const res = []for (let i = 0; i < list.length; i++) {const item = list[i]if (item[type] === value) {if ((packDisabledkey && item.disabled) || !item.disabled) {res.push(item)}}}return res
}/*** 获取所有指定的key值* @param type* @param value* @author crlang(https://crlang.com)*/
export function getAllNodeKeys(list, type, value, packDisabledkey = true) {if (!list || list.length === 0) {return []}const res = []for (let i = 0; i < list.length; i++) {const item = list[i]if (item[type] === value) {if ((packDisabledkey && item.disabled) || !item.disabled) {res.push(item.key)}}}return res
}

相关文章:

uniapp实现目录树效果,异步加载数据

uniapp目录树 父组件调用目录树组件 <DaTreeVue2:data"treeData":field"{label: name,key: id,}"change"handleTreeChange":defaultCheckedKeys"addressDefaultCheckedKey":defaultExpandedKeys"addressDefaultCheckedKey&qu…...

机器学习--网格搜索

引言 在机器学习的广袤世界里&#xff0c;构建一个性能卓越的模型是众多从业者不懈追求的目标。而模型性能的好坏&#xff0c;很大程度上依赖于超参数的设置。今天&#xff0c;我们就来深入探讨一种常用且有效的超参数调优方法 —— 网格搜索。 一、什么是网格搜索 网格搜索…...

Asp.NET Core WebApi 创建带鉴权机制的Api

构建一个包含 JWT&#xff08;JSON Web Token&#xff09;鉴权的 Web API 是一种常见的做法&#xff0c;用于保护 API 端点并验证用户身份。以下是一个基于 ASP.NET Core 的完整示例&#xff0c;展示如何实现 JWT 鉴权。 1. 创建 ASP.NET Core Web API 项目 使用 .NET CLI 或 …...

同步电路与异步电路详解

一、基本概念与核心区别 特性同步电路异步电路时钟依赖依赖全局时钟信号&#xff08;如CLK&#xff09;统一触发所有操作无全局时钟&#xff0c;依赖事件&#xff08;如信号跳变&#xff09;或握手协议时序控制所有操作在时钟边沿&#xff08;上升/下降沿&#xff09;同步执行…...

Vccaux_IO在DDR3接口中的作用

一、Vccaux_IO在DDR3接口中的作用 1.vccaux_io通常为FPGA的IO bank的辅助电源&#xff0c;用于支持特定电压的IO标准 2.在DDR3接口中&#xff0c;FPGA的IO bank需要DDR3芯片的电压(1.5v/1.35v)匹配 3.Vccaux_IO用于为FPGA的DDR3接口I/O Bank供电&#xff0c;其电压值、噪声和稳…...

5分钟读懂ArgoCD:在Kubernetes中实现持续部署

Kubernetes中的Argo CD介绍 Argo CD是用于Kubernetes的声明式GitOps持续交付工具。它遵循GitOps模式&#xff0c;以Git仓库作为定义所需应用程序状态的唯一真实来源&#xff0c;能在指定的目标环境中自动部署应用程序&#xff0c;并持续监控应用程序的运行状态&#xff0c;确保…...

Redis与Caffeine的结合使用详解(高效的二级缓存解决方案)

目录 一、Redis与Caffeine的结合使用&#xff08;一&#xff09;引入依赖&#xff08;二&#xff09;配置缓存&#xff08;三&#xff09;配置 Caffeine 缓存&#xff08;四&#xff09;配置 Redis 缓存&#xff08;五&#xff09;使用缓存 二、总结 一、Redis与Caffeine的结合…...

leetcode 322. Coin Change

这道题也是完全背包问题。注意与第518题和第377题对比。 这道题要求的是最少可以用多少个物品装满背包&#xff0c;不关心所选物品的组合方式和排列方式。因此&#xff0c;外层循环既可以是对物品的遍历&#xff0c;也可以是对容量的遍历。 第518题&#xff0c;要求的是装满背…...

mac|使用scrcpy实现无线Android投屏

scrcpy是一个开源项目&#xff0c;从项目的releases可以得知它适用于windows、linux、mac github&#xff1a;https://github.com/Genymobile/scrcpy/releases github中提供了应用于mac系统的静态版本&#xff08;也就是上图的scrcpy-macos-aarch64-v3.1.tar.gz和scrcpy-macos…...

2025年04月11日Github流行趋势

项目名称&#xff1a;ml-course 项目地址url&#xff1a;https://github.com/girafe-ai/ml-course项目语言&#xff1a;Jupyter Notebook历史star数&#xff1a;2880今日star数&#xff1a;207项目维护者&#xff1a;neychev, girafeai, v-goncharenko, vmarchenkoff, HCL-271项…...

深入浅出Redis 缓存使用问题 | 长文分享

目录 数据一致性 先更新缓存&#xff0c;后更新数据库【一般不考虑】 先更新数据库&#xff0c;再更新缓存【一般不考虑】 先删除缓存&#xff0c;后更新数据库 先更新数据库&#xff0c;后删除缓存【推荐】 怎么选择这些方案&#xff1f;采用哪种合适&#xff1f; 缓存…...

PINN:用深度学习PyTorch求解微分方程

神经网络技术已在计算机视觉与自然语言处理等多个领域实现了突破性进展。然而在微分方程求解领域&#xff0c;传统神经网络因其依赖大规模标记数据集的特性而表现出明显局限性。物理信息神经网络(Physics-Informed Neural Networks, PINN)通过将物理定律直接整合到学习过程中&a…...

Ubuntu vs CentOS:Shell 环境加载机制差异分析

CentOS与Ubuntu Shell环境加载机制差异及解决方案 一、问题现象还原 在 Ubuntu 系统中&#xff0c;希望登录时 /etc/profile.d/ipenv.sh 脚本未自动执行&#xff0c;而在 CentOS 上正常工作的根本原因是&#xff1a; Ubuntu 和 CentOS 采用了不同的 shell 初始化机制&#x…...

在 macOS 上修改 最大文件描述符限制(Too many open files) 和 网络端口相关参数 需要调整系统级配置的详细步骤

在 macOS 上修改 最大文件描述符限制&#xff08;Too many open files&#xff09; 和 网络端口相关参数 需要调整系统级配置。以下是详细步骤&#xff1a; 在 macOS 上修改 最大文件描述符限制&#xff08;Too many open files&#xff09; 和 网络端口相关参数 需要调整系统级…...

C语言 |位域结构体

在C语言中&#xff0c;位域结构体&#xff08;Bit-field Structure&#xff09;是一种通过按位分配内存优化存储空间的数据结构&#xff0c;特别适用于需要精确控制二进制位操作的场景&#xff08;如嵌入式开发、硬件寄存器操作等&#xff09;。以下是关于位域结构体的核心要点…...

Charles抓包-安装和IOS抓包指导

网络抓包工具使用指南 下载安装 目前市面上主流的抓包工具包括Charles和Sniff Master。其中Charles是一款老牌抓包工具&#xff0c;功能强大&#xff1b;而Sniff Master作为后起之秀&#xff0c;界面简洁&#xff0c;操作更加人性化。 建议从官网下载最新版本&#xff1a; …...

Redis 学习目标

&#x1f3af; Redis 学习目标&#xff08;开发者视角&#xff09; ✅ 一、学习完成后能掌握的核心能力&#xff1a; 分类具体内容&#x1f4e6; 基础能力熟练掌握 Redis 五大数据结构&#xff08;String、List、Hash、Set、ZSet&#xff09;&#xff0c;会用也会选对场景&am…...

Redis最佳实践——性能优化技巧之Pipeline 批量操作

Redis Pipeline批量操作在电商应用中的性能优化技巧 一、Pipeline核心原理与性能优势 1. 工作机制对比&#xff1a; sequenceDiagramtitle 常规请求 vs Pipeline请求# 常规模式Client->>Redis: 命令1Redis-->>Client: 响应1Client->>Redis: 命令2Redis--&g…...

Redis 集群(Cluster)

1. Redis 集群概述 Redis 集群是一种分布式架构&#xff0c;旨在提供数据分区和高可用性。它能够通过将数据分散到多个节点上来扩展 Redis&#xff0c;使其能够处理更多的数据量和更高的并发请求。Redis 集群实现了自动分片、故障转移和复制等功能。 Redis 集群与传统的单节点…...

XSS 跨站SVGPDFFlashMXSSUXSS配合上传文件添加脚本

#MXSS &#xff1a; https://www.fooying.com/the-art-of-xss-1-introduction/ #UXSS &#xff1a; Universal Cross-Site Scripting&#xff08;一般是浏览器自身的问题&#xff09; UXSS 是利用浏览器或者浏览器扩展漏洞来制造产生 XSS 并执行代码的一种攻击类型。 MICR…...

数据库主从延迟全解析:原因、影响与解决之道

目录 一、引言&#xff1a;理解数据库主从架构 二、数据库主从延迟的定义与测量 2.1 主从延迟的技术定义 2.2 如何测量主从延迟 2.3 主从延迟对系统的影响 三、主从延迟的常见原因分析 3.1 网络延迟因素 3.1.1 网络质量与带宽限制 3.1.2 地理位置分布造成的延迟 3.2 …...

BERT、T5、ViT 和 GPT-3 架构概述及代表性应用

BERT、T5、ViT 和 GPT-3 架构概述 1. BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09; 架构特点 基于 Transformer 编码器&#xff1a;BERT 使用多层双向 Transformer 编码器&#xff0c;能够同时捕捉输入序列中每个词的左右上下文信息…...

第十七天 - Jenkins API集成 - 流水线自动化 - 练习:CI/CD流程优化

前言 在DevOps实践中&#xff0c;持续集成与持续交付&#xff08;CI/CD&#xff09;是现代软件工程的核心支柱。作为业界使用最广泛的自动化服务器&#xff0c;Jenkins凭借其强大的插件生态和灵活的流水线配置能力&#xff0c;成为企业级CI/CD落地的首选工具。本文将深入解析J…...

SageAttention2

“SageAttention2: Efficient Attention with Thorough Outlier Smoothing and Per-thread INT4 Quantization”由Jintao Zhang等人撰写。文章提出SageAttention2&#xff0c;通过线程级INT4量化、Q矩阵平滑、两级累加策略等技术&#xff0c;在提升注意力计算效率的同时保持精度…...

.NET WPF 可视化树(Visual Tree)

.NET WPF 可视化树&#xff08;Visual Tree&#xff09; WPF 的可视化树&#xff08;Visual Tree&#xff09;是描述用户界面元素层级关系的核心概念之一&#xff0c;它与逻辑树&#xff08;Logical Tree&#xff09;共同构成了 WPF 的 UI 架构。以下是关于 WPF 可视化树的详细…...

磁盘存储下红黑树、B 树与 B + 树的原理、操作及对比

前置知识 磁盘 在计算机系统中&#xff0c;数据存储与检索效率深刻影响着整体性能。磁盘作为大容量数据的主要载体&#xff0c;其独特的 I/O 特性与树状数据结构的结合&#xff0c;催生出 B 树与 B 树这两种经典方案。了解它们如何适配磁盘存储&#xff0c;是揭开数据库、文…...

kubernetes》》k8s》》Volume 数据卷 PVC PV NFS

为啥需要数据卷 容器磁盘上的文件的生命周期是短暂的&#xff0c;这就使得在容器中运行重要应用时会出现一些问题。首先&#xff0c;当容器崩溃时&#xff0c;kubelet会重启它&#xff0c;但是容器中的文件将丢失——容器以干净的状态&#xff08;镜像最初的状态&#xff09;重…...

支持多格式且免费的图片转换工具推荐

软件介绍 今天要给大家推荐一款超好用的开源图片格式转换工具。这款工具完全免费&#xff0c;没有广告的干扰&#xff0c;让用户在使用过程中极为舒心。 ImageConverter图片格式转换 这款工具使用起来相当便捷&#xff0c;无需进行安装操作&#xff0c;只要轻轻双击图标&…...

DAPP实战篇:使用web3.js实现前端输入钱包地址查询该地址的USDT余额—操作篇

专栏:区块链入门到放弃查看目录-CSDN博客文章浏览阅读396次。为了方便查看将本专栏的所有内容列出目录,按照顺序查看即可。后续也会在此规划一下后续内容,因此如果遇到不能点击的,代表还没有更新。声明:文中所出观点大多数源于笔者多年开发经验所总结,如果你想要知道区块…...

K8S-证书更新时-误删除组件-

K8S 证书更新时-吴删除组件 [rootmaster ~] eth0 172.17.64.32 # docker rm -f docker ps | grep -E apiserver|scheduler|controller-manager| awk {print$1} 7856f2a3068e 2e1a6956d8a1 e9e3cb7870a9 31b19f4e2b22 c028146f88a5 abe4207808a3 [rootmaster ~] eth0 172.17.…...

第二章 Python爬虫篇—数据解析与提取

目录 一.数据解析概述 二.re解析和正则表达式 三.bs4解析-HTML语法 四.Xpath解析 此章节主要讲解&#xff1a;数据解析概述、re模块、bs4解析-html语法、xpath解析以及正则表达式。其中正则表达式我已经写过相关笔记&#xff0c;这里浅略叙述&#xff0c;如果不懂请看我笔记…...

数据仓库标准库模型架构相关概念浅讲

数据仓库与模型体系及相关概念 数据仓库与数据库的区别可参考&#xff1a;数据库与数据仓库的区别及关系_数据仓库和数据库-CSDN博客 总之&#xff0c;数据库是为捕获数据而设计&#xff0c;数据仓库是为分析数据而设计 数据仓库集成工具 在一些大厂中&#xff0c;其会有自…...

【区块链+ 人才服务】特范云区块链教学管理平台 | FISCO BCOS 应用案例

北京特范云科技有限公司利用大数据与人工智能等核心技术优势&#xff0c; 构建了“学、练、赛、评”一体化智慧体育课堂&#xff0c;促进教育技术、体育科学、IT 技术与体育教学的深度融合。公司首次提出了“体育动作积木”的教学概念&#xff0c; 通过区块链技术将学生的体测体…...

第一节:React 基础篇-React虚拟DOM原理及Diff算法优化策略

必考点&#xff1a;虚拟DOM树对比&#xff08;同级比较、Key的作用、组件类型判断&#xff09; 延伸&#xff1a;React 18中并发更新对Diff算法的影响 React虚拟DOM原理及Diff算法优化策略 虚拟DOM核心原理 概念&#xff1a; • 虚拟DOM&#xff08;Virtual DOM&#xff09;…...

MQTT的构成、使用场景、工作原理介绍

一、MQTT内容简介 MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级、基于发布-订阅模式的消息传输协议【适用于资源受限的设备和低带宽、高延迟或不稳定的网络环境】它在物联网应用中广受欢迎&#xff0c;能够实现传感器、执行器和其它设备之间的…...

idea光标变成白色方块的解决方法

在使用 IDEA 进行编程时&#xff0c;你可能会遇到这样一个情况&#xff1a;原本纤细的光标突然变成了白色粗块&#xff0c;这不仅影响视觉体验&#xff0c;还可能在输入时带来困扰。别担心&#xff0c;本文将为你详细剖析该问题出现的原因&#xff0c;并提供有效的解决办法。​…...

python manimgl数学动画演示_微积分_线性代数原理_ubuntu安装问题[已解决]

1.背景 最近调研python opencv, cuda加速矩阵/向量运算, 对于矩阵的线性变换, 秩, 转秩, 行列式变化等概概念模糊不清. 大概课本依旧是天书, 于是上B站搜索线性代数, 看到 3Blue1Brown 线性变换本质 视频, 点击观看. 惊为天人 --> 豁然开朗 --> 突然顿悟 --> 开心不已…...

如何为C++实习做准备?

博主介绍&#xff1a;程序喵大人 35- 资深C/C/Rust/Android/iOS客户端开发10年大厂工作经验嵌入式/人工智能/自动驾驶/音视频/游戏开发入门级选手《C20高级编程》《C23高级编程》等多本书籍著译者更多原创精品文章&#xff0c;首发gzh&#xff0c;见文末&#x1f447;&#x1…...

Linux 安装 vscode

使用包管理器安装&#xff08;推荐&#xff09; 对于基于 Debian 的系统&#xff08;如 Ubuntu&#xff09;&#xff1a; sudo apt update sudo apt install software-properties-common apt-transport-https wget -qO- https://packages.microsoft.com/keys/microsoft.asc …...

淘宝商品数据实时抓取 API 开发指南:从接口申请到数据解析实战

一、引言​ 在当今电商蓬勃发展的时代&#xff0c;淘宝作为国内电商巨头&#xff0c;其平台上汇聚了海量商品信息。对于电商从业者、数据分析爱好者以及众多依赖淘宝商品数据开展业务的企业而言&#xff0c;能够实时获取淘宝商品数据具有极高价值。例如&#xff0c;电商运营者…...

明远智睿SSD2351核心板在物联网领域的应用实践

物联网作为当今科技发展的热门领域&#xff0c;将无数设备连接在一起&#xff0c;实现数据的采集、传输与共享&#xff0c;构建起一个智能化的世界。在这庞大的物联网体系中&#xff0c;核心板扮演着至关重要的角色&#xff0c;明远智睿SSD2351核心板以其独特优势&#xff0c;在…...

这种情况是应为VScode的版本太新了,更新到1.86版本后要求远程连接服务器的内核版本不符合条件

这种情况是应为VScode的版本太新了&#xff0c;更新到1.86版本后要求远程连接服务器的内核版本不符合条件 解决方法 vscode降级&#xff0c;使用1.86以前的版本。亲测这种方法成功解决 首先关闭VSCode自动更新 Windows下载1.85版本链接&#xff1a;https://update.code.visua…...

996引擎-源码学习:PureMVC Lua 中的 Facade 类

996引擎-源码学习:PureMVC Lua 中的 Facade 类 1. 核心概念1.1 外观模式1.2 多例模式2. 关键组件NotificationController:ModelView3. 主要功能4. 初始化流程5. 通信机制6. 生命周期管理1. Facade 初始化流程图2. 发送通知时序图中介者 PlayerBestRingLayerMediatorOpenLayer …...

前端学习10—Ajax

1 AJAX 简介 AJAX 全称为 Asynchronous JavaScript And XML&#xff0c;就是异步的 JS 和 XML 通过 AJAX 可以在浏览器中向服务器发送异步请求&#xff0c;最大优势为&#xff1a;无刷新获取数据 AJAX 不是新的编程语言&#xff0c;而是一种将现有的标准组合在一起使用的新方…...

python的多线程和多进程程序编程

CPU密集型使用多进程&#xff0c;IO密集型使用多线程 查看进程ID和线程ID的命令分别是os.getpid()和threading.current_thread() 多进程使用multiprocessing就可以了&#xff0c;通常使用进程池来完成操作&#xff0c;阻塞主进程使用join方法 多线程使用threading模块&#…...

Python代码解释

文章目录 代码解析执行过程等价写法其他类似操作 这段代码使用了 Python 的 map() 函数和 lambda 表达式来对列表中的每个元素进行平方运算。让我详细解释一下&#xff1a; 代码解析 numbers [1, 2, 3, 4] squared list(map(lambda x: x**2, numbers))numbers [1, 2, 3, …...

DNS正反向解析复习,DNS主从服务,转发服务及DNS和nginx联合案例(不断更新)

正向解析 1、配置主机名 [rootlocalhost ~]# dnf install bash-completion -y #一个按tap键补全的软件 [rootlocalhost ~]# hostnamectl hostname dns #改主机名为dns [rootlocalhost ~]# exit ssh root你的IP地址 要重启才会生效2、安装bind [rootdns ~]# dnf install b…...

甜心速达智慧潮流精选超市、即时零售新业态,打造可持续发展商业模式

四川甜心速达科技有限公司、现公司运营高管团队均为美团高级运营师&#xff0c;公司高管团队人均获得“全国工商联人才交流服务中心”创业指导师、市场营销师等、公司致力于优化线上店铺人效比和资源匹配等问题&#xff0c;已经实现了对即时零售行业的资源整合&#xff0c;并融…...

大白话聊MySQL覆盖索引

目录 一、什么是覆盖索引&#xff1f;二、使用了覆盖索引 vs 没使用覆盖索引的区别三、例子说明四、总结 &#x1f31f;我的其他文章也讲解的比较有趣&#x1f601;&#xff0c;如果喜欢博主的讲解方式&#xff0c;可以多多支持一下&#xff0c;感谢&#x1f917;&#xff01; …...

C++ inline和define(宏)

文章目录 Inline 函数是什么意思&#xff1f;C中哪些函数不能声明为inline?内联(inline)函数和 #define&#xff08;宏&#xff09; Inline 函数是什么意思&#xff1f; inline是内联的意思&#xff0c;可以定义比较小的函数。因为函数频繁调用会占用很多的栈空间&#xff0c…...