ztree 是一个很经典的基于jquey开发的树结构编辑展示UI组件库。
https://gitee.com/zTree/zTree_v3
gitee上有一个很适合vue使用的ztree封装库,
https://gitee.com/astinlee_admin/Vue-Giant-Tree/tree/master
但是这个库有个问题。
打包后的代码引入到项目中会报错。
怎么办呢?
此时,我们应该“格局打开”,打包不行,不打包,作为代码片段引入不就可以了?
其实这个项目里面关键的只有一个文件,ztree.vue。
<template> <div class="ztree" :id="ztreeId"></div> </template> <script> import * as $ from "jquery"; if(!window.jQuery){ window.jQuery = $; } require("@ztree/ztree_v3/js/jquery.ztree.all"); export default { props: { setting: { type: Object, require: false, default: function(){ return {} } }, nodes: { type: Array, require: true, default: function(){ return [] } } }, data(){ return { ztreeId: 'ztree_'+ parseInt(Math.random() * 1e10), ztreeObj: null, list: [], ztreeSetting: { view: { showIcon: false // default to hide icon }, callback: { onAsyncError: (...arg) => { this.$emit('onAsyncError', ...arg) }, onAsyncSuccess: (...arg) => { this.$emit('onAsyncSuccess', ...arg) }, onCheck: (...arg) => { this.$emit('onCheck', ...arg) }, onClick: (...arg) => { this.$emit('onClick', ...arg) }, onCollapse: (...arg) => { this.$emit('onCollapse', ...arg) }, onDblClick: (...arg) => { this.$emit('onDblClick', ...arg) }, onDrag: (...arg) => { this.$emit('onDrag', ...arg) }, onDragMove: (...arg) => { this.$emit('onDragMove', ...arg) }, onDrop: (...arg) => { this.$emit('onDrop', ...arg) }, onExpand: (...arg) => { this.$emit('onExpand', ...arg) }, onm ouseDown: (...arg) => { this.$emit('onMouseDown', ...arg) }, onm ouseUp: (...arg) => { this.$emit('onMouseUp', ...arg) }, onRemove: (...arg) => { this.$emit('onRemove', ...arg) }, onRename: (...arg) => { this.$emit('onRename', ...arg) }, onRightClick: (...arg) => { this.$emit('onRightClick', ...arg) } } } } }, watch: { nodes: { handler: function(nodes){ this.list = nodes; // update tree if(this.ztreeObj){ this.ztreeObj.destroy(); } this.$nextTick(() => { this.ztreeObj = $.fn.zTree.init($("#"+this.ztreeId), Object.assign({}, this.ztreeSetting, this.setting), this.list); this.$emit('onCreated', this.ztreeObj) }) }, deep: true, immediate: true } } } </script> <style scoped> /* beauty ztree! */ .ztree { text-align:left; font-size: 14px; } .ztree >>> li { list-style-type: none; white-space: nowrap; outline: none; } .ztree >>> li ul { position: relative; padding: 0 0 0 20px; margin: 0; } .ztree >>> .line:before { position: absolute; top: 0; left: 10px; height: 100%; content: ''; border-right: 1px dotted #dbdbdb; } .ztree >>> .roots_docu:before, .ztree >>> .roots_docu:after, .ztree >>> .center_docu:before, .ztree >>> .bottom_docu:before, .ztree >>> .center_docu:after, .ztree >>> .bottom_docu:after { position: absolute; content: ''; border: 0 dotted #dbdbdb; } .ztree >>> .roots_docu:before { left: 10px; height: 50%; top:50%; border-left-width: 1px; } .ztree >>> .roots_docu:after { top: 50%; left: 11px; width: 50%; border-top-width: 1px; } .ztree >>> .center_docu:before { left: 10px; height: 100%; border-left-width: 1px; } .ztree >>> .center_docu:after { top: 50%; left: 11px; width: 50%; border-top-width: 1px; } .ztree >>> .bottom_docu:before { left: 10px; height: 50%; border-left-width: 1px; } .ztree >>> .bottom_docu:after { top: 50%; left: 11px; width: 50%; border-top-width: 1px; } .ztree >>> li a { display: inline-block; line-height: 22px; height: 22px; margin: 0; padding: 0 3px; cursor: pointer; transition: none; vertical-align: middle; color: #555555; } .ztree >>> .curSelectedNode { color: #000; border-radius: 4px; background-color: #c9e9f7; } .ztree >>> .curSelectedNode_Edit { height: 20px; opacity: 0.8; color: #000; border: 1px #6cc2e8 solid; background-color: #9dd6f0; } .ztree >>> .tmpTargetNode_inner { opacity: 0.8; color: #fff; background-color: #4fcbf0; filter: alpha(opacity=80); } .ztree >>> .rename { font-size: 12px; line-height: 22px; width: 80px; height: 22px; margin: 0; padding: 0; vertical-align: top; border: 0; background: none; } .ztree >>> .button { position: relative; display: inline-block; line-height: 22px; height: 22px; width: 22px; cursor: pointer; text-align: center; vertical-align: middle; } .ztree >>> .button.edit { color: #25ae88; } .ztree >>> .button.remove { color: #CB4042; } .ztree >>> .button.chk { position: relative; width: 14px; height: 14px; margin: 0 4px 0 0; border: 1px solid #d7dde4; border-radius: 2px; background: #fff; } .ztree >>> .chk.radio_true_full, .ztree >>> .chk.radio_false_full, .ztree >>> .chk.radio_true_full_focus, .ztree >>> .chk.radio_false_full_focus, .ztree >>> .chk.radio_false_disable, .ztree >>> .chk.radio_true_disable, .ztree >>> .chk.radio_true_part, .ztree >>> .chk.radio_false_part, .ztree >>> .chk.radio_true_part_focus, .ztree >>> .chk.radio_false_part_focus { border-radius: 8px; } .ztree >>> .button.chk:after { position: absolute; top: 1px; left: 4px; width: 4px; height: 8px; content: ''; transition: -webkit-transform 0.2s ease-in-out; transition: transform 0.2s ease-in-out; transition: transform 0.2s ease-in-out, -webkit-transform 0.2s ease-in-out; -webkit-transform: rotate(0deg) scale(0); transform: rotate(0deg) scale(0); border-right: 2px solid #fff; border-bottom: 2px solid #fff; } .ztree >>> .button.checkbox_false_full_focus { border-color: #ccc; } .ztree >>> .button.checkbox_true_full, .ztree >>> .button.checkbox_true_full_focus, .ztree >>> .button.checkbox_true_part, .ztree >>> .button.checkbox_true_part_focus, .ztree >>> .button.checkbox_true_disable { border-color: #39f; background-color: #39f; } .ztree >>> .button.checkbox_true_full:after, .ztree >>> .button.checkbox_true_full_focus:after, .ztree >>> .button.checkbox_true_disable:after { -webkit-transform: rotate(45deg) scale(1); transform: rotate(45deg) scale(1); } .ztree >>> .button.checkbox_true_part:after, .ztree >>> .button.checkbox_true_part_focus:after { top: 5px; left: 2px; width: 10px; height: 1px; -webkit-transform: rotate(0deg) scale(1); transform: rotate(0deg) scale(1); border-right: 0; } .ztree >>> .button.radio_true_full, .ztree >>> .chk.radio_true_full_focus, .ztree >>> .chk.radio_true_part, .ztree >>> .chk.radio_true_part_focus { border-color: #39f; } .ztree >>> .button.radio_true_full:after, .ztree >>> .chk.radio_true_full_focus:after, .ztree >>> .chk.radio_true_part:after, .ztree >>> .chk.radio_true_part_focus:after { top: 3px; left: 3px; width: 8px; -webkit-transform: rotate(0deg) scale(1); transform: rotate(0deg) scale(1); border: 0; border-radius: 4px; background: #39f; } .ztree >>> .button.checkbox_true_disable, .ztree >>> .button.checkbox_false_disable, .ztree >>> .chk.radio_false_disable, .ztree >>> .chk.radio_true_disable { cursor: not-allowed; } .ztree >>> .button.checkbox_false_disable { background-color: #f3f3f3; } .ztree >>> .button.noline_close:before, .ztree >>> .button.noline_open:before, .ztree >>> .button.root_open:before, .ztree >>> .button.root_close:before, .ztree >>> .button.roots_open:before, .ztree >>> .button.roots_close:before, .ztree >>> .button.bottom_open:before, .ztree >>> .button.bottom_close:before, .ztree >>> .button.center_open:before, .ztree >>> .button.center_close:before { position: absolute; top: 5px; left: 5px; content: ''; transition: -webkit-transform ease 0.3s; transition: transform ease 0.3s; transition: transform ease 0.3s, -webkit-transform ease 0.3s; -webkit-transform: rotateZ(0deg); transform: rotateZ(0deg); -webkit-transform-origin: 25% 50%; transform-origin: 25% 50%; border: 6px solid; border-color: transparent transparent transparent #666; } .ztree >>> .button.noline_open:before, .ztree >>> .button.root_open:before, .ztree >>> .button.roots_open:before, .ztree >>> .button.bottom_open:before, .ztree >>> .button.center_open:before { -webkit-transform: rotateZ(90deg); transform: rotateZ(90deg); } .ztree >>> .button.ico_loading { margin-right: 2px; background: url('data:image/gif;base64,R0lGODlhEAAQAKIGAMLY8YSx5HOm4Mjc88/g9Ofw+v///wAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQFCgAGACwAAAAAEAAQAAADMGi6RbUwGjKIXCAA016PgRBElAVlG/RdLOO0X9nK61W39qvqiwz5Ls/rRqrggsdkAgAh+QQFCgAGACwCAAAABwAFAAADD2hqELAmiFBIYY4MAutdCQAh+QQFCgAGACwGAAAABwAFAAADD1hU1kaDOKMYCGAGEeYFCQAh+QQFCgAGACwKAAIABQAHAAADEFhUZjSkKdZqBQG0IELDQAIAIfkEBQoABgAsCgAGAAUABwAAAxBoVlRKgyjmlAIBqCDCzUoCACH5BAUKAAYALAYACgAHAAUAAAMPaGpFtYYMAgJgLogA610JACH5BAUKAAYALAIACgAHAAUAAAMPCAHWFiI4o1ghZZJB5i0JACH5BAUKAAYALAAABgAFAAcAAAMQCAFmIaEp1motpDQySMNFAgA7') 0 center no-repeat; } .ztree >>> .tmpTargetzTree { opacity: 0.8; background-color: #2EA9DF; filter: alpha(opacity=80); } .ztree >>> .tmpzTreeMove_arrow { position: absolute; width: 18px; height: 18px; color: #4fcbf0; } .ztree >>> .ztree.zTreeDragUL { overflow: hidden; position: absolute; width: auto; height: auto; margin: 0; padding: 0; opacity: 0.8; border: 1px #176b53 dotted; background-color: #dbdbdb; filter: alpha(opacity=80); } .zTreeMask { position: absolute; z-index: 10000; opacity: 0.0; background-color: #cfcfcf; filter: alpha(opacity=0); } </style>ztree.vue
这样我们的项目文件引入这个文件就可以了。
我们现在还有2个问题
1 确保测试json是个正常的json文件。
这里有个正常的json,可以拿去用。
{ "code": 10000, "success": true, "data": [{ "id": "779893942852403200-1", "taskId": "779893942852403200", "zxbNum": null, "struId": "", "name": "-", "orgCode": "", "isLeaf": false, "majCode": "1", "taskOrder": 0, "children": [{ "id": "779893942852403200-1-13862", "taskId": "779893942852403200", "zxbNum": 1, "struId": "13862", "name": "-", "orgCode": "9767", "isLeaf": false, "majCode": "1", "taskOrder": 2, "children": [{ "id": "779893942852403200-1-13823", "taskId": "779893942852403200", "zxbNum": 1, "struId": "13823", "name": "-", "orgCode": "9728", "isLeaf": false, "majCode": "1", "taskOrder": 3, "children": [{ "id": "779893942852403200-1-14013", "taskId": "779893942852403200", "zxbNum": 1, "struId": "14013", "name": "-", "orgCode": "9918", "isLeaf": true, "majCode": "1", "taskOrder": 4, "children": [], "struType": "6" }], "struType": "5" }], "struType": "4" }], "struType": "" }, { "id": "779893942852403200-3", "taskId": "779893942852403200", "zxbNum": null, "struId": "", "name": "-", "orgCode": "", "isLeaf": false, "majCode": "3", "taskOrder": 0, "children": [{ "id": "779893942852403200-3-13862", "taskId": "779893942852403200", "zxbNum": 1, "struId": "13862", "name": "-", "orgCode": "9767", "isLeaf": false, "majCode": "3", "taskOrder": 2, "children": [{ "id": "779893942852403200-3-13823", "taskId": "779893942852403200", "zxbNum": 1, "struId": "13823", "name": "-", "orgCode": "9728", "isLeaf": true, "majCode": "3", "taskOrder": 3, "children": [], "struType": "5" }], "struType": "4" }], "struType": "" }, { "id": "779893942852403200-4", "taskId": "779893942852403200", "zxbNum": null, "struId": "", "name": "-", "orgCode": "", "isLeaf": false, "majCode": "4", "taskOrder": 0, "children": [{ "id": "779893942852403200-4-13862", "taskId": "779893942852403200", "zxbNum": 1, "struId": "13862", "name": "-", "orgCode": "9767", "isLeaf": false, "majCode": "4", "taskOrder": 2, "children": [{ "id": "779893942852403200-4-13823", "taskId": "779893942852403200", "zxbNum": 1, "struId": "13823", "name": "-", "orgCode": "9728", "isLeaf": false, "majCode": "4", "taskOrder": 3, "children": [{ "id": "779893942852403200-4-14013", "taskId": "779893942852403200", "zxbNum": 1, "struId": "14013", "name": "-", "orgCode": "9918", "isLeaf": true, "majCode": "4", "taskOrder": 4, "children": [], "struType": "6" }], "struType": "5" }], "struType": "4" }], "struType": "" }], "msg": "操作成功" }JSON
2 可以修改ztree的样式。
这个问题就比较复杂了,因为不同的DOM结构,很难保证ztree的样式可以改的和原来的(elementUI)完全一致。
但是至少改一个icon是没啥问题的。
假设我们不喜欢ztree的默认样式,而且想用UI图标库(比如font awasome)去代替原来的图标。
我们可以研究一下原来ztree的样式,然后对症下药去修改。
这个可以看下我最后贴的完整版引用代码。
<template> <div id="app" class="flex-col"> <h1 class="T"> Vue-Giant-Tree <a href="https://github.com/tower1229/Vue-Giant-Tree" target="_blank" titie="Vue-Giant-Tree" > <svg class="octicon octicon-mark-github v-align-middle" height="32" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true" > <path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z" /> </svg> </a> </h1> <div class="wrap flex-1"> <div id="c" class="c"> <tree :setting="setting" :nodes="nodes" @onClick="onClick" @onCheck="onCheck" @onCreated="handleCreated" /> </div> </div> <div class="toolbar"> <button class="btn" type="button" @click="update">更新数据</button> </div> <footer class="foot"> <p> © 2019 - 3019 Author <a href="https://refined-x.com/" target="_blank">前端路上</a> </p> </footer> </div> </template> <script> const bigData = require("@/mock/big-tree.json"); // const bigData2 = require("@/mock/tree.json"); // const bigData3 = require("@/mock/json_a.json"); const bigData4 = require("@/mock/taskdata.json"); // const simpleData = [ // { id: 1, pid: 0, name: "随意勾选 1", open: true }, // { id: 11, pid: 1, name: "随意勾选 1-1", open: true }, // { id: 111, pid: 11, name: "随意勾选 1-1-1" }, // { id: 112, pid: 11, name: "随意勾选 1-1-2" }, // { id: 12, pid: 1, name: "随意勾选 1-2", open: true }, // { id: 121, pid: 12, name: "随意勾选 1-2-1" }, // { id: 122, pid: 12, name: "随意勾选 1-2-2" }, // { id: 2, pid: 0, name: "随意勾选 2", checked: true, open: true }, // { id: 21, pid: 2, name: "随意勾选 2-1" }, // { id: 22, pid: 2, name: "随意勾选 2-2", open: true }, // { id: 221, pid: 22, name: "随意勾选 2-2-1", checked: true }, // { id: 222, pid: 22, name: "随意勾选 2-2-2" }, // { id: 23, pid: 2, name: "随意勾选 2-3" } // ]; const dataQueue = [bigData.data, bigData4.data]; export default { name: "app", components: { tree: resolve => require(["./components/ztree.vue"], resolve) }, data() { return { showIndex: 0, setting: { check: { enable: false }, data: { simpleData: { enable: true, pIdKey: "pid" } } } }; }, computed: { nodes: function() { return dataQueue[this.showIndex]; } }, methods: { onClick: function(evt, treeId, treeNode) { // 点击事件 console.log(evt.type, treeNode); }, onCheck: function(evt, treeId, treeNode) { // 选中事件 console.log(evt.type, treeNode); }, handleCreated: function(ztreeObj) { // onCreated 中操作ztreeObj对象展开第一个节点 ztreeObj.expandNode(ztreeObj.getNodes()[0], true); }, update: function() { // 更新示例数据 this.showIndex = this.showIndex === 0 ? 1 : 0; } } }; </script> <style> html,body{height: 100%;} body { margin: 0; } /* flex栅格 */ .flex-col { overflow: hidden; display: -ms-box; display: -ms-flexbox; display: flex; flex-direction: column; -ms-flex-direction: column; } .flex-row { overflow: hidden; display: -ms-box; display: -ms-flexbox; display: flex; } .flex-1 { -ms-flex: 1; flex: 1; min-width: 0; } .flex-2 { -ms-flex: 2; flex: 2; min-width: 0; } .flex-3 { -ms-flex: 3; flex: 3; min-width: 0; } .flex-4 { -ms-flex: 4; flex: 4; min-width: 0; } .align-stretch { -ms-align-items: stretch; -ms-flex-align: stretch; align-items: stretch; } .align-center { -ms-align-items: center; -ms-flex-align: center; align-items: center; } .justify-center { -ms-box-pack: center; -ms-flex-pack: center; justify-content: center; } #app { height: 100%; font-family: "Avenir", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; } .wrap{ overflow: hidden; } .c { width: 600px; height: 100%; overflow: auto; margin: auto; } .T { font-size: 34px; margin: 0 0 30px; height: 170px; line-height: 260px; overflow: hidden; background:url(./assets/logo.png) center no-repeat; } .toolbar { margin: 20px auto; } .toolbar .btn { padding: 0.5em 1em; outline: none; border-radius: 4px; } .foot { margin-top: 30px; background: #333; padding: 24px; overflow: hidden; color: #999; font-size: 14px; text-align: center; } .foot a { color: #fff; margin: 0 0.5em; } #c .ztree .button.noline_close:before, #c .ztree .button.noline_open:before, #c .ztree .button.root_open:before, #c .ztree .button.root_close:before, #c .ztree .button.roots_open:before, #c .ztree .button.roots_close:before, #c .ztree .button.bottom_open:before, #c .ztree .button.bottom_close:before, #c .ztree .button.center_open:before, #c .ztree .button.center_close:before { content: "\f196"; position: absolute; right: 0px; top:3px; font: normal normal normal 14px/1 FontAwesome; font-size: 17px; text-rendering: auto; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; color: #999999; } #c .ztree .button.noline_open:before, #c .ztree .button.root_open:before, #c .ztree .button.roots_open:before, #c .ztree .button.bottom_open:before, #c .ztree .button.center_open:before { content: "\f147"; position: absolute; right: 0px; top:3px; font: normal normal normal 14px/1 FontAwesome; font-size: 17px; text-rendering: auto; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; transform: unset; color: #009280; } </style>App.vue
标签:...,vue,button,arg,ztree,使用,true,before From: https://www.cnblogs.com/foxcharon/p/17855827.html