简单分析说下为啥卡顿(具体查看参考文章):vue
具体查看参考文章node
不经过 props 传递,而是经过函数传递。ios
// 父组件
<huge-tree ref="huge-tree"></huge-tree>
axios.get(`/static/json/${count}.json`).then(({ data }) => {
// 注意:这里的 data 也不要被依赖收集了,会致使卡顿。
this.$refs['huge-tree'].setData(data);
});
// 子组件
<script>
class BigData {
_data = []; // 海量数据 tree
list = []; // 扁平化的tree
filterList = []; // 根据关键词过滤后的list
listMap = {}; // this.big.list 对应的 map, 便于快速找到节点。
filterTree = []; // 根据关键词过滤后的tree
}
export default {
data() {
this.big = null;
return {
count: 1, // 用于视图更新, 因为没有依赖收集,经过count 手动更新computed。
keyword: '', // 关键词
isSearching: false, // 搜索中
itemHeigth: 27, // 每一项的高度
startIndex: 0, // 渲染的开始区间
endIndex: 70, // 渲染的结束区间
throttleSrcoll: '', // 节流
debounceInput: '',
isOnlyInCheckedSearch: false,
};
},
computed: {
// 过滤掉 hidden 节点
unHiddenList() {
return this.count ? this.big.filterList.filter(i => !i.isHidden) : [];
},
// 虚拟高度,与隐藏的数量有关
phantomHeight() {
return this.unHiddenList.length * this.itemHeigth;
},
renderList() {
return this.unHiddenList.slice(this.startIndex, this.endIndex);
},
},
created() {
this.big = new BigData();
// 滚动时的节流
this.throttleSrcoll = throttle(this.setRenderRange, 80);
// 输入过滤条件的防抖
this.debounceInput = debounce(this.init, 300);
},
methods: {
setData(data) {
this.big._data = data;
this.init('init');
},
//init: 1. 拉平tree,2. 组织list,3. 过滤,4. 展开,5. 选中, 6. 回到顶部
init(op) {
// op: init, restore, showCheckedOnly
if (this.big._data.length === 0) return;
if (op === 'init') {
this.flatTree(this.big._data);
this.big.list.forEach(node => (this.big.listMap[node.id] = node));
}
this.initFilter(op);
if (op === 'init' || op === 'restore') this.initExpand();
this.setCheckedKeys(this.big.checkedKeys);
this.backToTop();
},
//......
}
}
</script>
复制代码
zhuanlan.zhihu.com/p/55528376git
源码github