ant-design-vue 에서 tree 추가 삭제 작업 방법
19587 단어 ant-design-vuetree첨삭 하여 고치다
새 프로젝트 에 서 는
ant-design-vue
구성 요소 라 이브 러 리 를 사 용 했 습 니 다.이 구성 요소 라 이브 러 리 는 완전히 기본 데이터 가 양 방향 으로 연결 되 는 모드 로 구현 되 었 습 니 다.폼 구성 요소 만 소량의 방법 을 제공 합 니 다.따라서 ant-design-vue
을 사용 할 때 데이터 변경 측면 에서 UI 디 스 플레이 효 과 를 전환 해 야 합 니 다.그러나 트 리 제어 장치 a-tree
의 사용 에 있어 서 데이터 구동 만 고려 하면 체험 효과 가 좋 지 않 습 니 다.2.현재 통 증
공식 도움말 문 서 를 읽 고 트 리 컨트롤 데이터 바 인 딩 을 해 야 합 니 다.데이터 구 조 를
children,title,key
속성 을 포함 하 는 큰 대상 으로 만들어 야 합 니 다.이러한 대상 은 백 엔 드 를 통 해 이러한 json 대상 을 구성 하거나 백 엔 드 를 통 해 전단 에 json 배열 을 만들어 야 합 니 다.전단 근 은 상하 관계 에 따라 이러한 트 리 대상 을 구축 합 니 다.데이터 바 인 딩 이 잘 되 어 있 습 니 다.우리 가 원 하 는 UI 효 과 를 성공 적 으로 표현 할 수 있 습 니 다.그런데 아 픈 점 은 어디 에 있 습 니까?3.데이터 구동 은 트 리 노드 의 삭제 와 수정 을 실현 한다.
도움말 문서 에서
selectedKeys(.sync)
속성 을 찾 을 수 있 습 니 다.sync
은 이 속성 이 양 방향 동작 을 지원 한 다 는 것 을 표시 합 니 다.그러나 여기 서 얻 은 것 은 key
값 일 뿐 필요 한 바 인 딩 대상 이 아 닙 니 다.따라서 이 key 값 을 통 해 이 대상 을 찾 아야 합 니 다.이 대상 을 찾 아야 하 는 것 은 상당히 역 겨 운 일 입 니 다.b.목록 데이터 의 대상 과 구축 후 대응 하 는 노드 가 같은 대상 주소 라면 이 목록 데 이 터 를 직접 찾 아 대응 하 는 대상 을 얻 을 수 있 습 니 다.
그래서 징 그 러 운 부분 은 바로 나 무 를 구축 하 는 것 이다.나 는 이 나 무 를 옮 겨 다 니 며 특정한 노드 를 찾 거나 방안 b 라 는 공간 으로 시간 을 바 꾸 는 방법 을 사용 해 야 한다.
여기 서 우 리 는 데이터 가 이미 트 리 로 구 축 된 데이터 형식 이 라 고 가정 합 니 다.데이터 구동 을 실현 하 는 가장 중요 한 임 무 는 두 가지 핵심 방법 을 완성 해 야 합 니 다.
getTreeDataByKey
getTreeParentChilds
// author:herbert date:20201024 qq:464884492
// key
getTreeDataByKey(childs = [], findKey) {
let finditem = null;
for (let i = 0, len = childs.length; i < len; i++) {
let item = childs[i]
if (item.key !== findKey && item.children && item.children.length > 0) {
finditem = this.getTreeDataByKey(item.children, findKey)
}
if (item.key == findKey) {
finditem = item
}
if (finditem != null) {
break
}
}
return finditem
},
// author:herbert date:20201024 qq:464884492
// key children
getTreeParentChilds(childs = [], findKey) {
let parentChilds = []
for (let i = 0, len = childs.length; i < len; i++) {
let item = childs[i]
if (item.key !== findKey && item.children && item.children.length > 0) {
parentChilds = this.getTreeParentChilds(item.children, findKey)
}
if (item.key == findKey) {
parentChilds = childs
}
if (parentChilds.length > 0) {
break
}
}
return parentChilds
},
3.1 동급 노드 추가같은 등급 의 노드 를 추가 하려 면 새로 추 가 된 데 이 터 를 현재 선택 한 노드 의 부모 급
children
배열 에 추가 해 야 합 니 다.따라서 노드 를 추가 하 는 난점 은 현재 선택 한 노드 의 바 인 딩 대상 의 부모 급 대상 을 어떻게 찾 는 지 입 니 다.페이지 코드 는 다음 과 같 습 니 다.
<!-- author:herbert date:20201030 qq:464884492-->
<a-card style="width: 450px;height:550px;float: left;">
<div slot="title">
<h2> ( )<span style="color:blue">@herbert</span></h2>
<div>
<a-button @click="dataDriveAddSame"> </a-button>
<a-divider type="vertical" />
<a-button @click="dataDriveAddSub"> </a-button>
<a-divider type="vertical" />
<a-button @click="dataDriveModify"> </a-button>
<a-divider type="vertical" />
<a-button @click="dataDriveDelete"> </a-button>
</div>
</div>
<a-tree :tree-data="treeData" :defaultExpandAll="true"
:selectedKeys.sync="selectKeys" showLine />
<img src="./assets/gamelogo.png" width="100%" style="margin-top:20px" />
</a-card>
페이지 코드 에서 알 수 있 듯 이 트 리 에 두 개의 속성 tree-data
,selectedKeys
이 연결 되 어 있 습 니 다.여기 서 우 리 는 selectedKeys
바 인 딩 값 을 통 해 트 리 가 현재 선택 한 key
값 을 얻 을 수 있 습 니 다.그리고 사용 방법 getTreeParentChilds
을 사용 하면 같은 등급 의 추 가 를 실현 할 수 있 습 니 다.따라서 사용 하 는 dataDriveAddSame
코드 에 대해 다음 과 같이 실현 할 수 있 습 니 다.
// author:herbert date:20201030 qq:464884492
dataDriveAddSame() {
let parentChilds = this.getTreeParentChilds(this.treeData, this.selectKeys[0])
parentChilds.forEach(item => console.log(item.title));
parentChilds.push({
title: ' , ',
key: new Date().getTime()
})
},
3.2 다음 레벨 추가위의 기초 가 있 으 면 다음 단 계 를 추가 하 는 것 이 간단 합 니 다.유일 하 게 주의해 야 할 것 은 대상 children 속성 이 존재 하지 않 을 수 있 습 니 다.이때$set 방식 으로 속성
dataDriveAddSub
코드 를 추가 하여 다음 과 같이 실현 해 야 합 니 다.
// author:herbert date:20201030 qq:464884492
dataDriveAddSub() {
let selectItem = this.getTreeDataByKey(this.treeData, this.selectKeys[0])
if (!selectItem.children) {
this.$set(selectItem, "children", [])
}
selectItem.children.push({
title: , ,
key: new Date().getTime()
})
this.$forceUpdate()
},
3.3 수정 노드바 인 딩 대상 을 얻 을 수 있 고 노드 값 을 수정 하 는 것 도 간단 해 졌 습 니 다.하급 자 를 추가 하 는 것 과 같이
getTreeDataByKey
을 사용 하여 현재 대상 을 얻 은 다음 에 직접 값 을 수정 하면 됩 니 다.dataDriveModify
코드 는 다음 과 같 습 니 다.
// author:herbert date:20201030 qq:464884492
dataDriveModify() {
let selectItem = this.getTreeDataByKey(this.treeData, this.selectKeys[0])
selectItem.title = ' , '
},
3.4 노드 삭제같은 등급 을 추가 하 는 것 과 마찬가지 로 부모 급 노드
children
배열 을 찾 아야 합 니 다.현재 대상 이 부모 급 배열 에 대응 하 는 색인 입 니 다.dataDriveDelete
코드 는 다음 과 같 습 니 다.
// author:herbert date:20201030 qq:464884492
dataDriveDelete() {
let parentChilds = this.getTreeParentChilds(this.treeData, this.selectKeys[0])
let delIndex = parentChilds.findIndex(item => item.key == this.selectKeys[0])
parentChilds.splice(delIndex, 1)
},
4.슬롯 방식 으로 트 리 노드 추가 삭제ant-tree
api 에서 트 리 노드 속성 title
유형 은 문자열 일 수도 있 고 슬롯 일 수도 있 습 니 다.
<!-- author:herbert date:20201030 qq:464884492-->
<a-card style="width: 450px;height:550px;float: left;">
<div slot="title">
<h2> ( )</h2>
<div>
, <span style="color:blue">@ </span>
</div>
</div>
<a-tree ref="tree1" :tree-data="treeData1" :defaultExpandAll="true" :selectedKeys.sync="selectKeys1" showLine blockNode>
<template v-slot:title="nodeData">
<span>{{nodeData.title}}</span>
<a-button-group style="float:right">
<a-button size="small" @click="slotAddSame(nodeData)" icon="plus-circle" title=" "></a-button>
<a-button size="small" @click="slotAddSub(nodeData)" icon="share-alt" title=" "></a-button>
<a-button size="small" @click="slotModify(nodeData)" icon="form" title=" "></a-button>
<a-button size="small" @click="slotDelete(nodeData)" icon="close-circle" title=" "></a-button>
</a-button-group>
</template>
</a-tree>
<img src="./assets/gamelogo.png" width="100%" style="margin-top:20px" />
</a-card>
4.1 동급 추가슬롯 방식 으로 대상 을 얻 을 수 있 습 니 다.사실은 현재 노드 에 대응 하 는 속성 값 이 고 얕 은 복사 본 입 니 다.소스 코드
string|slot|slot-scope
중의 vc-tree\src\TreeNode.jsx
에서 다음 과 같은 코드 를 찾 을 수 있 습 니 다.
const currentTitle = title;
let $title = currentTitle ? (
<span class={`${prefixCls}-title`}>
{typeof currentTitle === 'function'
? currentTitle({ ...this.$props, ...this.$props.dataRef }, h)
: currentTitle}
</span>
) : (
<span class={`${prefixCls}-title`}>{defaultTitle}</span>
);
이 코드 에서 dataRef 를 볼 수 있 습 니 다.그러나 공식 도움말 문서 에 서 는 이러한 속성 에 대한 소개 가 전혀 없습니다.소스 코드 를 보 려 는 학생 에 게 주 는 복지 인지 아 닌 지 모 르 겠 습 니 다.코드 차원 에서 보 든 디 버 깅 결 과 를 보 든 역할 영역 을 통 해 얻 은 대상 은 부모 속성 이 없 기 때문에 같은 등급 의 추 가 를 실현 할 수 없습니다.renderSelector
코드 는 다음 과 같 습 니 다.
// author:herbert date:20201030 qq:464884492
slotAddSame(nodeItem) {
console.log(nodeItem)
this.$warn({ content: " , , ! , " })
},
4.2 다음 레벨 추가대상 을 얻 었 지만 던 전 하나 입 니 다.그래서
slotAddSame
을 설치 해도 소 용 없습니다!!
// author:herbert date:20201030 qq:464884492
slotAddSub(nodeItem) {
if (!nodeItem.children) {
console.log(' , ')
this.$set(nodeItem, "children", [])
}
nodeItem.children.push({
title: this.addSubTitle,
key: new Date().getTime(),
scopedSlots: { title: 'title' },
children: []
})
},
4.3 수정 노드수정 도 마찬가지 로 실현 할 수 없 지만 위 에
children
이 언급 되 어 있 습 니 다.여기 서 간단하게 사용 하면 title 값 을 수정 할 수 있 습 니 다.
// author:herbert date:20201030 qq:464884492
slotModify(nodeItem) {
console.log(nodeItem)
console.log('nodeItem Treenode , Title ')
nodeItem.title = ' , '
// dataRef
nodeItem.dataRef.title = nodeItem.title
},
4.4 노드 삭제삭제 도 안 되 는 게 분명 해.
// author:herbert date:20201030 qq:464884492
slodDelete(nodeItem) {
console.log(nodeItem)
this.$warn({ content: " , , ! , " })
delete nodeItem.dataRef
},
5.트 리 이벤트 결합 dataRef 구현위 에 서 는 슬롯 방식 을 통 해 수정 기능 만 실 현 했 습 니 다.특히 실 망 스 럽 습 니 다.하지만 디자인 의 측면 에서 볼 때 대상 에 게 사용자 정의 렌 더 링 을 도와 주 는 것 만으로 도 좋 습 니 다.공식 Api 를 계속 읽 고 사건 중의
dataRef
사건 이 제공 하 는 값 을 찾 아 우리 에 게 큰 발휘 공간 을 주 었 습 니 다.얼마나 큰 지,원본 코드 를 찾 아 보 겠 습 니 다.우선 select
이벤트 코드 를 찾 았 습 니 다.select
파일 에서 구체 적 인 코드 는 다음 과 같 습 니 다.
onSelect(e) {
if (this.isDisabled()) return;
const {
vcTree: { onNodeSelect },
} = this;
e.preventDefault();
onNodeSelect(e, this);
},
코드 에서 볼 수 있 듯 이 components\vc-tree\src\TreeNode.jsx
onSelect 는 TreeNode
중의 onNode Selected 방법 을 호출 하 는 것 입 니 다.Tree
까지 해당 하 는 코드 를 찾 으 면 다음 과 같 습 니 다.
onNodeSelect(e, treeNode) {
let { _selectedKeys: selectedKeys } = this.$data;
const { _keyEntities: keyEntities } = this.$data;
const { multiple } = this.$props;
const { selected, eventKey } = getOptionProps(treeNode);
const targetSelected = !selected;
// Update selected keys
if (!targetSelected) {
selectedKeys = arrDel(selectedKeys, eventKey);
} else if (!multiple) {
selectedKeys = [eventKey];
} else {
selectedKeys = arrAdd(selectedKeys, eventKey);
}
// [Legacy] Not found related usage in doc or upper libs
const selectedNodes = selectedKeys
.map(key => {
const entity = keyEntities.get(key);
if (!entity) return null;
return entity.node;
})
.filter(node => node);
this.setUncontrolledState({ _selectedKeys: selectedKeys });
const eventObj = {
event: 'select',
selected: targetSelected,
node: treeNode,
selectedNodes,
nativeEvent: e,
};
this.__emit('update:selectedKeys', selectedKeys);
this.__emit('select', selectedKeys, eventObj);
},
두 가지 방법 을 결합 하면 Tree 노드 eventObj 대상 에서 알 수 있 듯 이 구성 요소 components\vc-tree\src\Tree.jsx
은 Tree 노드 를 TreeNode 캐 시 데이터 select
과 실제 적 인 TreeNode 노드 selectedNodes
을 호출 자 에 게 제공 할 뿐만 아니 라 이 node 속성 이 있 으 면 우 리 는 해당 노드 의 상하 관 계 를 얻 을 수 있다.다음은 이 재 도움말 문서 에 나타 나 지 않 은
node
이 어떤 귀신 인지 말씀 드 리 겠 습 니 다.파일
dataRef
이 대응 하 는 components\tree\Tree.jsx
함수 에서 우 리 는 Tree 가 vc-tree 구성 요소 에 render
속성 을 전달 해 야 한 다 는 것 을 알 수 있 습 니 다.우리 가 최종 적 으로 사용 하 는 전달 노드 데이터 도 이 속성 명 입 니 다.두 단락 의 관건 코드 는 다음 과 같 습 니 다.
render(){
...
let treeData = props.treeData || treeNodes;
if (treeData) {
treeData = this.updateTreeData(treeData);
}
...
if (treeData) {
vcTreeProps.props.treeData = treeData;
}
return <VcTree {...vcTreeProps} />;
}
위의 코드 를 통 해 알 수 있 듯 이 구성 요소 의 바 텀 호출 방법 treeData
은 우리 가 들 어 온 데 이 터 를 처리 했다.이 방법 은 관건 적 인 코드 가 다음 과 같다.
updateTreeData(treeData) {
const { $slots, $scopedSlots } = this;
const defaultFields = { children: 'children', title: 'title', key: 'key' };
const replaceFields = { ...defaultFields, ...this.$props.replaceFields };
return treeData.map(item => {
const key = item[replaceFields.key];
const children = item[replaceFields.children];
const { on = {}, slots = {}, scopedSlots = {}, class: cls, style, ...restProps } = item;
const treeNodeProps = {
...restProps,
icon: $scopedSlots[scopedSlots.icon] || $slots[slots.icon] || restProps.icon,
switcherIcon:
$scopedSlots[scopedSlots.switcherIcon] ||
$slots[slots.switcherIcon] ||
restProps.switcherIcon,
title:
$scopedSlots[scopedSlots.title] ||
$slots[slots.title] ||
restProps[replaceFields.title],
dataRef: item,
on,
key,
class: cls,
style,
};
if (children) {
// herbert 20200928
if (this.onlyLeafEnable === true) {
treeNodeProps.disabled = true;
}
return { ...treeNodeProps, children: this.updateTreeData(children) };
}
return treeNodeProps;
});
},
}
이 방법 에서 우 리 는 updateTreeData
속성 에서 treeNodeProps
속성 을 찾 았 습 니 다.그 값 은 바로 우리 가 dataRef
에 들 어 온 데이터 항목 입 니 다.그래서 이 속성 은 양 방향 연결 을 지원 합 니 다.이 treeData
은 최종 적 으로 treeNodeProps
,구성 요소 로 렌 더 링 됩 니 다.이 두 가지 지식 을 알 게 된 후에 우리 가 해 야 할 조작 은 간단 해 졌 다.사건 구동 페이지 코드 는 다음 과 같다.
<!-- author:herbert date:20201101 qq:464884492 -->
<a-card style="width: 450px;height:550px;float: left;">
<div slot="title">
<h2> ( dataRef)<span style="color:blue">@464884492</span></h2>
<div>
<a-button @click="eventAddSame"> </a-button>
<a-divider type="vertical" />
<a-button @click="eventAddSub"> </a-button>
<a-divider type="vertical" />
<a-button @click="eventModify"> </a-button>
<a-divider type="vertical" />
<a-button @click="eventDelete"> </a-button>
</div>
</div>
<a-tree :tree-data="treeData2" @select="onEventTreeNodeSelected" :defaultExpandAll="true" :selectedKeys.sync="selectKeys2" showLine />
<img src="./assets/gamelogo.png" width="100%" style="margin-top:20px" />
</a-card>
이벤트 구동 을 통 해 이 루어 진 이상,우 리 는 먼저 응당 받 아야 할 이벤트 에 등록 해 야 한다.코드 는 다음 과 같다.
// author:herbert date:20201101 qq:464884492
onEventTreeNodeSelected(seleteKeys, e) {
if (e.selected) {
this.eventSelectedNode = e.node
return
}
this.eventSelectedNode = null
},
이벤트 에서 저 희 는 현재 선택 한 TreeNode 를 저장 하여 추가 수정 과 삭 제 를 편리 하 게 합 니 다.5.1 동급 추가
vue 가상 dom 을 이용 하여 부모 레벨 을 찾 습 니 다.
// author:herbert date:20201101 qq:464884492
eventAddSame() {
//
let dataRef = this.eventSelectedNode.$parent.dataRef
if (!dataRef.children) {
this.$set(dataRef, 'children', [])
}
dataRef.children.push({
title: ' , ',
key: new Date().getTime()
})
},
5.2 다음 단계 추가직접 사용 대상
components\vc-tree\src\TreeNode.jsx
,dataRef
사용 children
방법 주의
// author:herbert date:20201101 qq:464884492
eventAddSub() {
let dataRef = this.eventSelectedNode.dataRef
if (!dataRef.children) {
this.$set(dataRef, 'children', [])
}
dataRef.children.push({
title: ' , bug ',
key: new Date().getTime(),
scopedSlots: { title: 'title' },
children: []
})
},
5.3 수정 노드$set
에 대응 하 는 값 을 직접 수정 합 니 다.
// author:herbert date:20201101 qq:464884492
eventModify() {
let dataRef = this.eventSelectedNode.dataRef
dataRef.title = ' , bug'
},
5.4 노드 삭제vue 가상 dom 을 통 해 부모 급
dataRef
을 찾 아 dataRef
에서 선택 항목 을 제거 하면 됩 니 다.
// author:herbert date:20201101 qq:464884492
eventDelete() {
let parentDataRef = this.eventSelectedNode.$parent.dataRef
//
const children = parentDataRef.children
const currentDataRef = this.eventSelectedNode.dataRef
const index = children.indexOf(currentDataRef)
children.splice(index, 1)
}
6.총화이 지식 포 인 트 는 demo 에서 최종 완성 까지 앞 뒤 가 빠 른 한 달 이 걸 립 니 다.그 동안 소스 코드 를 찾 고 테스트 를 하 는 데 시간 이 걸 립 니 다.하지만 이 점 을 분명하게 말 하면 가치 가 있다 고 생각 합 니 다!데모 소스 코드 가 필요 하 다 면 아래 의 QR 코드 를 스 캔 하 십시오.공중 번호[작은 마당 이 작 지 않 습 니 다]에 관심 을 가지 고
children
에 답 하여 얻 으 십시오.ant-tree
이라는 구성 요소 라 이브 러 리 에 대해 서 는 제 가 예전 에 사 용 했 던 ant-desgin-vue
구성 요소 라 이브 러 리 에 비해 웹 페이지 전시 에 적합 한 것 같 습 니 다.배경 시스템 을 만 들 려 면 대량의 조작 이 필요 합 니 다.아직 힘 이 부족 합 니 다.ant-design-vue 에서 tree 를 삭제 하고 고 치 는 방법 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 ant-design-vue 에서 tree 를 삭제 하고 고 치 는 내용 은 예전 의 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 부탁드립니다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
이진 트리의 경계 순회은 중복 노드 없이 왼쪽 경계, 잎, 오른쪽 경계를 포함하지만 노드의 값은 중복을 포함할 수 있습니다. 루트 노드에 왼쪽 및 오른쪽 하위 트리가 포함되어 있지 않으면 루트 노드 자체가 왼쪽 경계 또는 오른쪽 경계로 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.