vue ztree 的使用
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) }, onMouseDown: (...arg) => { this.$emit('onMouseDown', ...arg) }, onMouseUp: (...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>
这样我们的项目文件引入这个文件就可以了。
我们现在还有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": "操作成功" }
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>
posted on 2023-11-25 17:51 fox_charon 阅读(591) 评论(0) 收藏 举报
 
 
                
            
         
 
         浙公网安备 33010602011771号
浙公网安备 33010602011771号