应当指出,antd 是有 ztree 组件的,但是太简单,无法满足复杂的业务需求。
所以我还是决定使用zTree.
- 用 npm | cnpm 或者 yarn | tyarn 安装,这一步略。
- 在 jsx 文件最上面引入。
import $$ from '@/utils/jquery-vendor.js' import zTree from 'zTree'; //样式文件一定不要忘了引入,不然会没有样式 import 'ztree/css/zTreeStyle/zTreeStyle.css';
注意这个 jquery-vendor.js。它是让 zTree 可以正常工作的代码。
因为 zTree 并没有考虑到 node 环境的问题——它假定 jQuery 一定在 window 对象下。
jquery-vendor.js:import $ from 'jquery' window.$ = $ window.jQuery = $ export default $
- 在合适的生命周期中渲染它。
let ZtreeObject let self
componentWillMount() { self = this dispatch({ type: 'personalWorkBranch/fetchZSKFL_Tree', payload: { ...userInfo, zsfl_id: 'all' }, }).then(() => { const { ZSFLTreeData } = this.props if (Array.isArray(ZSFLTreeData) && ZSFLTreeData.length > 0) { this.initZtree(ZSFLTreeData) } }); }
无关代码都删除掉了。
self 需要在 react 类的之外声明一下。
当然也需要在结束时的声明周期销毁。componentWillUnmount() { self = null if (ZtreeObject) { ZtreeObject.destroy() } }
当然,最关键的是抽出来的渲染方法。
// ztree 初始化方法 initZtree = (zNodes) => { var setting = { view: { showLine: true, fontCss: {color:"#666"}, expandSpeed: "", addHoverDom: this.addHoverDom, removeHoverDom: removeHoverDom, selectedMulti: false }, edit: { enable: true, renameTitle: '类目修改', removeTitle: '类目删除' }, callback: { // before 执行之前 beforeRemove: this.beforeRemove, beforeRename: this.beforeRename, beforeClick: this.ztnBeforeClick, // on 执行之后 onClick: this.ztnOnClick } }; // var zNodes = [ // { id:1, pId:0, name:"父节点1 - 展开"}, // { id:11, pId:1, name:"父节点11 - 折叠"}, // { id:111, pId:11, name:"叶子节点111"}, // { id:112, pId:11, name:"叶子节点112"}, // { id:113, pId:11, name:"叶子节点113"}, // ]; // var zNodes = [ // { // id: 1, // name: "父节点1 - 展开", // children: [ // { // id: 11, // name: "父节点11 - 折叠", // children: [ // { // id: 111, // name: "叶子节点111" // }, // { // id: 112, // name: "叶子节点112" // }, // { // id: 113, // name: "叶子节点113" // } // ] // } // ] // } // ]; // var zNodes = [ // { // id: 1, // name: "父节点1 - 展开" // } // ]; ZtreeObject = $$.fn.zTree.init($("#tree"), setting, zNodes); }
到这里其实就可以了。
但是我们可能会需要一些增删改查的方法。
-
this.addHoverDom
// ztree 添加节点 addHoverDom = function (treeId, treeNode) { var sObj = $("#" + treeNode.tId + "_span"); if (treeNode.editNameFlag || $("#addBtn_"+treeNode.tId).length>0) return; var addStr = "<span class='button add' id='addBtn_" + treeNode.tId + "' title='类目新增' onfocus='this.blur();'></span>"; sObj.after(addStr); var btn = $("#addBtn_"+treeNode.tId); if (btn) btn.bind("click", function(){ const { dispatch } = self.props dispatch({ type: 'personalWorkBranch/fetchaddZSKFL', payload: { ...userInfo, fjzskfl_id: treeNode.id, flmc: '新节点' } }).then(() => { const { newTreeDataAfterAdd, commonStatus, commonMessage } = self.props const $ = $$ // console.log(newTreeDataAfterAdd) // console.log(commonStatus) // console.log(commonMessage) if (commonStatus == 201) { var zTree = $.fn.zTree.getZTreeObj(ztreeId); zTree.addNodes(treeNode, { id: newTreeDataAfterAdd.id, pId:treeNode.id, name: newTreeDataAfterAdd.name }); return false; } else if (commonStatus == 401) { message.error(commonMessage) return false; } else { return false; } }) // alert("?") // var zTree = $.fn.zTree.getZTreeObj("treeDemo"); // zTree.addNodes(treeNode, {id:(100 + newCount), pId:treeNode.id, name:"new node" + (newCount++)}); // return false; }); };
-
removeHoverDom
const removeHoverDom = function (treeId, treeNode) { $("#addBtn_"+treeNode.tId).unbind().remove(); };
-
this.beforeRemove
// ztree 删除节点 beforeRemove = (treeId, treeNode) => { // var zTree = $.fn.zTree.getZTreeObj("treeDemo"); // zTree.selectNode(treeNode); const zskfl_id = treeNode.id const fjzskfl_id = treeNode.getParentNode().id const { dispatch } = self.props dispatch({ type: 'personalWorkBranch/fetchdelZSKFL', payload: { ...userInfo, fjzskfl_id: fjzskfl_id, zskfl_id: zskfl_id } }).then(() => { const { commonStatus, commonMessage } = self.props // console.log(commonStatus) // console.log(commonMessage) const $ = $$ var zTree = $.fn.zTree.getZTreeObj(ztreeId); if (commonStatus == 201) { zTree.removeNode(treeNode) message.success(commonMessage) return false; } else if (commonStatus == 401) { message.error(commonMessage) return false; } else { return false } }) return false }
-
this.beforeRename
// ztree 编辑节点 beforeRename = (treeId, treeNode, newName) => { if (newName.length == 0) { setTimeout(function() { const $ = $$ var zTree = $.fn.zTree.getZTreeObj(ztreeId); zTree.cancelEditName(); message.warning("节点名称不能为空."); }, 0); return false; } const oldName = treeNode.name const zskfl_id = treeNode.id const zskfl_name = newName const { dispatch } = self.props dispatch({ type: 'personalWorkBranch/fetchupdateZSKFL', payload: { ...userInfo, zskfl_name: zskfl_name, zskfl_id: zskfl_id } }).then(() => { const { commonStatus, commonMessage } = self.props const $ = $$ var zTree = $.fn.zTree.getZTreeObj(ztreeId); // zTree.cancelSelectedNode(treeNode) // var node = zTree.getNodesByParam("key", zskfl_id, null) if (commonStatus == 201) { if (oldName === newName) { } else { message.success(commonMessage) } return false; // node.name = zskfl_name // zTree.updateNode(node) } else if (commonStatus == 401) { zTree.cancelEditName() message.error(commonMessage) return false; } else { zTree.cancelEditName() return false } }) return true }
-
this.ztnBeforeClick
// ztree 点击 ztnBeforeClick = (treeId, treeNode, clickFlag) => { return true }
-
this.ztnOnClick
// ztnOnClick = (e, treeId, treeNode, clickFlag) => { // console.log(treeNode) if (treeNode.isParent) { const { dispatch } = this.props; dispatch({ type: 'dicData/fetchDataZSFL', payload: { zsfl_id: treeNode.id ? treeNode.id : 'all' }, }) } }