精华内容
下载资源
问答
  • vue 树形结构

    2020-08-07 10:56:20
    触发 <el-button size="small" type="success" @click="handlecaidan(scope.row.id)">分配菜单</el-button> <!-- 分配菜单 -->...el-dialog title="分配菜单" :visible....-- --> <el-tre

    1.html

    触发
     <el-button size="small" type="success" @click="handlecaidan(scope.row.id)">分配菜单</el-button>
        <!-- 分配菜单 -->
        <el-dialog title="分配菜单" :visible.sync="handlecaidanis" width="40%">
          <!-- 树 -->
          <el-tree
            :data="treedata" //展示数据
            :props="defaultProps"//配置选项
            show-checkbox//节点是否可被选择
            node-key="id"//每个树节点用来作为唯一标识的属性,整棵树应该是唯一的
             ref="tree"
              default-expand-all//	是否默认展开所有节点
            :default-checked-keys="defKeys"//默认勾选的节点的 key 的数组
          >
          </el-tree>
          <span slot="footer" class="dialog-footer">
            <el-button @click="treerome">取 消</el-button>
            <el-button type="primary" @click="addfrom">确 定</el-button>
          </span>
        </el-dialog>
     
    

    2.data中定义

      handlecaidanis: false, //分配菜单
        // 树形数据
          treedata:[],
          id:'',//树形图确让修改的ID
          menustr:"",
          defKeys:[],
          defaultProps: {
            children: "children",
            label: "title"
          }
    

    3.methods

     //  点击分配权限
        handlecaidan(id) {
          this.id = id
          fetchListtree().then(response => {
            this.treedata = []
            for (var item in response.data) {
              this.treedata.push(response.data[item])
            }
          });
          treelistdata(id).then(response => {
          this.defKeys = response.data
            this.$nextTick(() => {
              this.$refs.tree.setCheckedKeys(this.defKeys)
            })
                this.handlecaidanis = true;
          })
        },
        // 分配取消
        treerome(){
        this.handlecaidanis = false
        this.$refs.tree.setCheckedKeys([]);
        },
        //分配确定
        addfrom(id){
          console.log(id);
          //选中的内容
           let checkedNodes = this.$refs.tree.getCheckedNodes();
            let checkedMenuIds=new Set();
             if(checkedNodes!=null&&checkedNodes.length>0){
              for(let i=0;i<checkedNodes.length;i++){
                let checkedNode = checkedNodes[i];
                checkedMenuIds.add(checkedNode.id);
              }
            }
              console.log(checkedMenuIds);
              this.menustr = JSON.stringify(checkedMenuIds)
              var data = {
                menustr:this.menustr
              }
              id = this.id
              console.log(data,id);
             fetchListWithtree(data,id).then(response => {
                 this.$message({
              message: response.errmsg,
              type: "success",
              duration: 1000
            });
             })
        this.handlecaidanis = false
       this.$refs.tree.setCheckedKeys([]);
        },
    
    展开全文
  • 主要介绍了vue树形结构获取键值的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • Vue树形结构数据格式化代码插件,封装的组件代码
  • Vue树形结构分页怎样实现?求思路? Vue树形结构分页怎样实现?求思路?
  • Vue树形结构操作

    万次阅读 2018-07-09 22:49:21
    树形结构是一种常用的数据结构,使用Vue怎么来渲染呢?要把树结构的每一个节点都渲染成dom,需要对树结构进行递归遍历。Vue组件可以通过name选项的设置来递归的调用自己,因此渲染起来很方便。 本文简单实现了一下...

            树形结构是一种常用的数据结构,使用Vue怎么来渲染呢?要把树结构的每一个节点都渲染成dom,需要对树结构进行递归遍历。Vue组件可以通过name选项的设置来递归的调用自己,因此渲染起来很方便。  

            本文简单实现了一下树结构的基本增删改等操作,后续还会继续对树结构渲染(比如拖拽操作、大数据量渲染效率等)进行探索。

    代码比较简单,MyTree组件:

    <template>
      <div class="my-tree">
        <div
          class="brother"
          v-for="(data, idx) of treeData"
          :key="idx">
          <div class="node">
            <span @click="data.expand=!data.expand">
              <Button class="node-expand" type="text" icon="chevron-down" v-if="data.expand"></Button>
              <Button class="node-expand" type="text" icon="chevron-right" v-else></Button>
            </span>
            <input class="node-name" v-model="data.name" />
            <span class="node-menu">
              <span class="menu-item" title="添加同级节点" @click.stop="$emit('addBrother', $event, data)">
                <Icon type="plus-round"></Icon>
              </span>
              <span class="menu-item" title="添加下级节点" @click.stop="$emit('addChild', $event, data)">
                <Icon type="ios-plus-outline"></Icon>
              </span>
              <span class="menu-item" title=“删除” @click.stop="$emit('deleteNode', $event, data)">
                <Icon type="trash-a"></Icon>
              </span>
            </span>
          </div>
          <div
            class="children"
            v-if="data.children && data.children.length"
            v-show="data.expand">
            <my-tree
              @addBrother="addBrother"
              @addChild="addChild"
              @deleteNode="deleteNode"
              :treeData="data.children">
            </my-tree>
          </div>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      name: 'my-tree',
      props: {
        treeData: {
          type: Array,
          default: () => [{
            id: 1,
            name: '一级节点1',
            expand: true,
            children: [{
              id: 2,
              expand: true,
              name: '二级节点1'
            }]
          },
          {
            id: 3,
            expand: true,
            name: '一级节点2',
            children: [{
              id: 4,
              expand: true,
              name: '二级节点1'
            },
            {
              id: 5,
              expand: true,
              name: '二级节点2',
              children: [{
                id: 6,
                expand: true,
                name: '三级节点'
              }]
            }]
          }]
        }
      },
      methods: {
        addBrother (event, data) {
          this.$emit('addBrother', event, data)
        },
        addChild (event, data) {
          this.$emit('addChild', event, data)
        },
        deleteNode (event, data) {
          this.$emit('deleteNode', event, data)
        }
      }
    }
    </script>
    
    <style lang="stylus" scoped>
    .children
      position relative
      padding-left 20px
    .node-expand
      width 1.5rem
      height 1.5rem
      padding-left 0
      padding-right 0
      padding-bottom 0
      padding-top 0
      &:focus
        box-shadow none
    
    .node-menu
      width 3rem
      display flex
      justify-content space-around
      .menu-item
        &:hover
          cursor pointer
    
    .brother
      display flex
      flex-direction column
      .node
        height 1.5rem
        display flex
        align-items center
        .node-name
          // border none
          // background none
          overflow-x visible
          &:focus
            outline none
    </style>

    组件使用,Tree.vue页面代码:

    <template>
      <div class="tree">
        <div class="tree-title">
          树结构
        </div>
        <my-tree
          @addBrother="addBrother"
          @addChild="addChild"
          @deleteNode="deleteNode">
        </my-tree>
      </div>
    </template>
    
    <script>
    import MyTree from '@/components/MyTree'
    
    export default {
      name: 'tree',
      components: {
        'my-tree': MyTree
      },
      data () {
        return {
          id: 100
        }
      },
      methods: {
        addBrother (event, data) {
          let parentData = this.getParentData(event.target)
          console.log(parentData)
          if (parentData) {
            let index = parentData.indexOf(data)
            if (index !== -1) {
              parentData.splice(index + 1, 0, this.newNode())
            }
          }
        },
        addChild (event, data) {
          if (!data.children) {
            this.$set(data, 'children', [])
          }
          data.children.push(this.newNode())
        },
        deleteNode (event, data) {
          let parentData = this.getParentData(event.target)
          if (parentData) {
            let index = parentData.indexOf(data)
            if (index !== -1) {
              parentData.splice(index, 1)
            }
          }
        },
        newNode () {
          let id = this.id++
          return {
            id,
            name: '新节点' + id,
            expand: true,
            children: []
          }
        },
        getParentData (node) {
          while (node && node.tagName !== 'BODY') {
            if (node.__vue__ && node.__vue__.$options.name === 'my-tree') {
              return node.__vue__.treeData
            }
            node = node.parentNode
          }
          return null
        }
      }
    }
    </script>
    
    <style lang="stylus" scoped>
    .tree
      padding 3rem 2rem
      text-align left
      .tree-title
        border-bottom 1px solid gray
        padding-bottom 0.5rem
        margin-bottom 1rem
    </style>

    这里使用了一些iView的图标标签,可以简单的使用iView来实现漂亮的效果,可以到其iView网了解使用方法。

    学习前端也几个月了,在开始使用Vue的很长一段时间里,对Vue一些选项的作用不甚了解,在Vue网都有比较清楚的介绍,比如递归渲染用到的name属性:

    name

    • 类型string

    • 限制:只有作为组件选项时起作用。

    • 详细

      允许组件模板递归地调用自身。注意,组件在全局用 Vue.component() 注册时,全局 ID 自动作为组件的 name。

    时常翻翻官网总会有意想不到的收获~。~

     

    展开全文
  • 怎么在vue中利用递归组件实现一个树形控件发布时间:2021-06-11 17:26:48来源:亿速云阅读:81作者:Leah本篇文章为大家展示了怎么在vue中利用递归组件实现一个...树形结构2Vue.component('tree',{name:"tree",templ...

    怎么在vue中利用递归组件实现一个树形控件

    发布时间:2021-06-11 17:26:48

    来源:亿速云

    阅读:81

    作者:Leah

    本篇文章为大家展示了怎么在vue中利用递归组件实现一个树形控件,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

    vue版的树形控件html>

    树形结构2

    Vue.component('tree', {

    name:"tree",

    template:`

    • {{ item.label }}

    `,

    props:["folder","select"],

    })

    // 

    var app = new Vue({

    el:"#app",

    data:{

    msg:"hello world",

    trees: [

    {

    id:1,

    label:"1级目录1",

    show:false,

    children:[

    {

    id:"1-1",

    label:"1.1目录"

    },

    {

    id:"1-2",

    label:"1.2目录"

    },

    {

    id:"1-3",

    label:"1.3目录"

    },

    ]

    },

    {

    id:2,

    label:"1级目录2",

    show:false

    },

    {

    id:3,

    label:"1级目录3",

    show:false,

    children:[

    {

    id:"3-1",

    label:"3.1目录"

    },

    {

    id:"3-2",

    label:"3.2目录",

    show:false,

    children:[

    {

    id:"3-2-1",

    label:"3.2.1目录"

    },

    {

    id:"3-2-2",

    label:"3.2.2目录"

    },

    {

    id:"3-2-3",

    label:"3.2.3目录"

    }

    ]

    }

    ]

    },

    {

    id:4,

    label:"1级目录4",

    show:false,

    children:[

    {

    id:"4-1",

    label:"4.1目录"

    },

    {

    id:"4-2",

    label:"4.2目录",

    show:false,

    children:[

    {

    id:"4-2-1",

    label:"4.2.1目录"

    }

    ]

    }

    ]

    },

    {

    id:5,

    label:"1级目录5",

    show:false,

    children:[

    {

    id:"5-1",

    label:"5.1目录",

    show:false,

    children:[

    {

    id:"5-1-1",

    label:"5.1.1目录"

    },

    {

    id:"5-1-2",

    label:"5.1.2目录",

    show:false,

    children:[

    {

    id:"5-1-2-1",

    label:"5.1.2.1目录"

    },

    ]

    }

    ]

    },

    {

    id:"5-2",

    label:"5.2目录",

    show:false

    }

    ]

    },

    ]

    },

    methods:{

    clickHandler(){

    console.log(23333);

    },

    select(data){

    console.log(data);

    }

    },

    mounted(){

    console.log(this.trees);

    }

    })

    看下结果

    e1f16658abc30390c98dd115b9f89875.png

    当然我用的全局组件,如果用vue-cli搭建的环境是一样的,引入组件就可以了,但是一定要注意,组件内必须要用name属性,而且name的名称要和组件名称(组件标签名称)一致才可以

    贴一个项目中用的模板吧,相当于做笔记了

    • {{ item.label }}

    import { mapGetters , mapActions} from 'vuex';

    export default{

    name:"DatabaseTree",

    props:["folder","select","currentId"],

    data(){

    return{

    addParams:{

    label:"",

    children:[]

    },

    noteData:{

    children:[]

    }

    }

    },

    computed:{

    ...mapGetters(["catalog"])

    },

    methods:{}

    }

    .dataBaseTree{

    padding-left:12%;

    line-height:40px;

    ul{

    padding-left:12%;

    line-height:40px;

    li{

    span{

    display:inline-block;

    padding-left:23%;

    height:100%;

    width:120%;

    color:#ababab;

    font-size:14px;

    position: relative;

    cursor: pointer;

    &:hover{

    background: #EDF0F5;

    }

    .folderIcon{

    color:#BCBCBC;

    position: absolute;

    top:-1px;

    left:22px;

    }

    }

    }

    }

    li{

    position: relative;

    span{

    display:inline-block;

    padding-left:40px;

    font-size:14px;

    height:100%;

    width:120%;

    cursor: pointer;

    position: relative;

    right:25px;

    top:-2px;

    color:#ababab;

    &:hover{

    background: #EDF0F5;

    }

    .titleIcon{

    color:#C3C3C3;

    font-size:16px;

    position: absolute;

    top:12px;

    left:16px;

    }

    .folderIcon{

    color:#BCBCBC;

    position: absolute;

    top:-1px;

    left:22px;

    }

    }

    .active{

    background: #EDF0F5;

    }

    }

    }

    vue版的就到这里了

    下面贴一个原生js版的,感兴趣的小伙伴可以继续往下看html>

    Document

    var tree=[

    {

    id:1,

    label:"1级目录1",

    children:[

    {

    id:"1-1",

    label:"1.1目录"

    },

    {

    id:"1-2",

    label:"1.2目录"

    },

    {

    id:"1-3",

    label:"1.3目录"

    },

    ]

    },

    {

    id:2,

    label:"1级目录2",

    },

    {

    id:3,

    label:"1级目录3",

    children:[

    {

    id:"3-1",

    label:"3.1目录"

    },

    {

    id:"3-2",

    label:"3.2目录",

    children:[

    {

    id:"3-2-1",

    label:"3.2.1目录"

    },

    {

    id:"3-2-2",

    label:"3.2.2目录"

    },

    {

    id:"3-2-3",

    label:"3.2.3目录"

    }

    ]

    }

    ]

    },

    {

    id:4,

    label:"1级目录4",

    children:[

    {

    id:"4-1",

    label:"4.1目录"

    },

    {

    id:"4-2",

    label:"4.2目录",

    children:[

    {

    id:"4-2-1",

    label:"4.2.1目录"

    }

    ]

    }

    ]

    },

    {

    id:5,

    label:"1级目录5",

    children:[

    {

    id:"5-1",

    label:"5.1目录",

    children:[

    {

    id:"5-1-1",

    label:"5.1.1目录"

    },

    {

    id:"5-1-2",

    label:"5.1.2目录",

    children:[

    {

    id:"5-1-2-1",

    label:"5.1.2.1目录"

    },

    ]

    }

    ]

    },

    {

    id:"5-2",

    label:"5.2目录"

    }

    ]

    },

    ];

    var render = function(tree) {

    if (!tree) return null

    var ul = document.createElement('ul');

    for(var i = 0; i 

    var li = document.createElement('li')

    // 创建span标签

    var span = document.createElement('span'); span.innerText = tree[i].label;

    li.appendChild(span);

    if(tree[i].children){

    var sub = render(tree[i].children);

    li.appendChild(sub);

    }

    ul.appendChild(li);

    }

    return ul

    };

    document.body.innerHTML = '';

    document.body.appendChild(render(tree));

    上述内容就是怎么在vue中利用递归组件实现一个树形控件,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。

    展开全文
  • vue 树形结构应用

    千次阅读 2018-11-08 20:42:13
    树形结构 说实话 el-tree 已经封装的挺好的 但是样式确实不敢恭维 所以就模仿了一个ztree结构形成 先看效果图吧   一说到树形结构 肯定涉及递归了 这是毋庸置疑的 看着图片 效果确实就是爽  想当年刚开始...

    树形结构 说实话 el-tree 已经封装的挺好的  但是样式确实不敢恭维  所以就模仿了一个ztree结构形成

    先看效果图吧

     

    一说到树形结构   肯定涉及递归了  这是毋庸置疑的   看着图片 效果确实就是爽  

    想当年刚开始写的时候真是要命呢   还是来一段代码吧

     

    <style lang="scss">
    div.ztree_content_wrap {
      height: 100%;
      overflow: hidden;
    }
    div.ztree_content_wrap div.left {
    }
    div.zTreeDemoBackground {
      width: 100%;
      text-align: left;
    }
    
    .expendIcon {
      background-position: -74px -36px;
      line-height: 0;
      margin: 0;
      width: 16px;
      height: 16px;
      display: inline-block;
      vertical-align: middle;
      border: 0 none;
      cursor: pointer;
      outline: none;
      position: absolute;
      top: 4px;
      background-color: transparent;
      background-repeat: no-repeat;
      background-attachment: scroll;
      background-image: url("../../../../static/img/zTreeStandard.png");
    }
    .el-container.left .el-main {
      border: 1px solid #ddd;
      margin-right: 5px;
    }
    ul.ztree {
      /* border: 1px solid #ddd; */
      background: #ffffff;
      width: 168px;
      overflow: hidden;
    }
    
    .ztree * {
      padding: 0;
      margin: 0;
      font-size: 12px;
      color: #74797b;
      /* font-family: Verdana, Arial, Helvetica, AppleGothic, sans-serif; */
      font-family: Microsoft YaHei, \\5fae\8f6f\96c5\9ed1, Helvetica Neue, Helvetica,
        PingFang SC, Hiragino Sans GB, Arial, sans-serif;
    }
    .ztree {
      margin: 0;
      padding: 5px;
      color: #333;
    }
    .ztree li {
      position: relative;
      padding: 0;
      margin: 0;
      list-style: none;
      line-height: 22px;
      text-align: left;
      white-space: nowrap;
      outline: 0;
    }
    .ztree li ul {
      margin: 0;
      padding: 0 0 0 18px;
    }
    .ztree li ul.line {
      background: url("../../../../static/img/zTreeStyle-line.png") 4px 0 repeat-y;
    }
    
    .ztree li a {
      padding: 1px 3px 0 1px;
      margin: 0;
      cursor: pointer;
      height: 17px;
      color: #333;
      background-color: transparent;
      text-decoration: none;
      vertical-align: top;
      display: inline-block;
    }
    .ztree li a:hover {
      text-decoration: underline;
      color: blue;
    }
    .ztree li a.curSelectedNode {
      padding-top: 0px;
      background-color: #191d22;
      color: #fff;
      height: 22px;
      border: 1px #191d22 solid;
      opacity: 0.8;
    }
    .ztree li a.curSelectedNode_Edit {
      padding-top: 0px;
      background-color: #ffe6b0;
      color: black;
      height: 16px;
      border: 1px #ffb951 solid;
      opacity: 0.8;
    }
    .ztree li a.tmpTargetNode_inner {
      padding-top: 0px;
      background-color: #316ac5;
      color: white;
      height: 16px;
      border: 1px #316ac5 solid;
      opacity: 0.8;
      filter: alpha(opacity=80);
    }
    .ztree li a.tmpTargetNode_prev {
    }
    .ztree li a.tmpTargetNode_next {
    }
    .ztree li a input.rename {
      height: 14px;
      width: 80px;
      padding: 0;
      margin: 0;
      font-size: 12px;
      border: 1px #7ec4cc solid;
      *border: 0px;
    }
    .ztree li span {
      line-height: 16px;
      margin-right: 2px;
      top: 3px;
      display: inline-block;
    }
    .ztree li span.button {
      line-height: 0;
      margin: 0;
      width: 16px;
      height: 16px;
      display: inline-block;
      vertical-align: middle;
      border: 0 none;
      cursor: pointer;
      outline: none;
      background-color: transparent;
      background-repeat: no-repeat;
      background-attachment: scroll;
      background-image: url("../../../../static/img/zTreeStandard.png");
      *background-image: url("../../../../static/img/zTreeStandard.gif");
    }
    
    .ztree li span.button.chk {
      width: 13px;
      height: 13px;
      margin: 0 3px 0 0;
      cursor: auto;
    }
    .ztree li span.button.chk.checkbox_false_full {
      background-position: 0 0;
    }
    .ztree li span.button.chk.checkbox_false_full_focus {
      background-position: 0 -14px;
    }
    .ztree li span.button.chk.checkbox_false_part {
      background-position: 0 -28px;
    }
    .ztree li span.button.chk.checkbox_false_part_focus {
      background-position: 0 -42px;
    }
    .ztree li span.button.chk.checkbox_false_disable {
      background-position: 0 -56px;
    }
    .ztree li span.button.chk.checkbox_true_full {
      background-position: -14px 0;
    }
    .ztree li span.button.chk.checkbox_true_full_focus {
      background-position: -14px -14px;
    }
    .ztree li span.button.chk.checkbox_true_part {
      background-position: -14px -28px;
    }
    .ztree li span.button.chk.checkbox_true_part_focus {
      background-position: -14px -42px;
    }
    .ztree li span.button.chk.checkbox_true_disable {
      background-position: -14px -56px;
    }
    .ztree li span.button.chk.radio_false_full {
      background-position: -28px 0;
    }
    .ztree li span.button.chk.radio_false_full_focus {
      background-position: -28px -14px;
    }
    .ztree li span.button.chk.radio_false_part {
      background-position: -28px -28px;
    }
    .ztree li span.button.chk.radio_false_part_focus {
      background-position: -28px -42px;
    }
    .ztree li span.button.chk.radio_false_disable {
      background-position: -28px -56px;
    }
    .ztree li span.button.chk.radio_true_full {
      background-position: -42px 0;
    }
    .ztree li span.button.chk.radio_true_full_focus {
      background-position: -42px -14px;
    }
    .ztree li span.button.chk.radio_true_part {
      background-position: -42px -28px;
    }
    .ztree li span.button.chk.radio_true_part_focus {
      background-position: -42px -42px;
    }
    .ztree li span.button.chk.radio_true_disable {
      background-position: -42px -56px;
    }
    
    .ztree li span.button.switch {
      width: 18px;
      height: 22px;
    }
    .ztree li span.button.root_open {
      background-position: -92px -53px;
    }
    .ztree li span.button.root_close {
      background-position: -74px -53px;
    }
    .ztree li span.button.roots_open {
      background-position: -92px 0;
    }
    .ztree li span.button.roots_close {
      background-position: -74px 0;
    }
    .ztree li span.button.center_open {
      background-position: -92px -17px;
    }
    .ztree li span.button.center_close {
      background-position: -74px -17px;
    }
    .ztree li span.button.bottom_open {
      background-position: -92px -36px;
    }
    .ztree li span.button.bottom_close {
      background-position: -74px -36px;
    }
    .ztree li span.button.noline_open {
      background-position: -92px -72px;
    }
    .ztree li span.button.noline_close {
      background-position: -74px -72px;
    }
    .ztree li span.button.root_docu {
      background: none;
    }
    .ztree li span.button.roots_docu {
      background-position: -56px 0;
    }
    .ztree li span.button.center_docu {
      background-position: -56px -16px;
    }
    .ztree li span.button.bottom_docu {
      background-position: -56px -36px;
    }
    .ztree li span.button.noline_docu {
      background: none;
    }
    
    .ztree li span.button.ico_open {
      margin-right: 2px;
      background-position: -110px -16px;
      vertical-align: top;
      *vertical-align: middle;
    }
    .ztree li span.button.ico_close {
      margin-right: 2px;
      background-position: -110px 0;
      vertical-align: top;
      *vertical-align: middle;
    }
    .ztree li span.button.ico_docu {
      margin-right: 2px;
      background-position: -110px -32px;
      vertical-align: top;
      *vertical-align: middle;
    }
    .ztree li span.button.edit {
      margin-right: 2px;
      background-position: -110px -48px;
      vertical-align: top;
      *vertical-align: middle;
    }
    .ztree li span.button.remove {
      margin-right: 2px;
      background-position: -110px -64px;
      vertical-align: top;
      *vertical-align: middle;
    }
    
    /*.ztree li span.button.ico_loading{margin-right:2px; background:url('../../static/images/loading.gif') no-repeat scroll 0 0 transparent; 
    	            vertical-align:top; *vertical-align:middle}*/
    
    ul.tmpTargetzTree {
      background-color: #ffe6b0;
      opacity: 0.8;
      filter: alpha(opacity=80);
    }
    
    span.tmpzTreeMove_arrow {
      width: 16px;
      height: 16px;
      display: inline-block;
      padding: 0;
      margin: 2px 0 0 1px;
      border: 0 none;
      position: absolute;
      background-color: white;
      background-repeat: no-repeat;
      background-attachment: scroll;
      background-position: -110px -80px;
      background-image: url("../../../../static/img/zTreeStandard.png");
      *background-image: url("../../../../static/img/zTreeStandard.gif");
    }
    
    ul.ztree.zTreeDragUL {
      margin: 0;
      padding: 0;
      position: absolute;
      width: auto;
      height: auto;
      overflow: hidden;
      background-color: #cfcfcf;
      border: 1px #00b83f dotted;
      opacity: 0.8;
      filter: alpha(opacity=80);
    }
    
    .zTreeMask {
      z-index: 10000;
      background-color: #cfcfcf;
      opacity: 0;
      filter: alpha(opacity=0);
      position: absolute;
    }
    
    .loadSyncNode {
      width: 16px;
      height: 16px;
      position: relative;
      display: inline-block;
      background-image: url("data:image/gif;base64,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");
    }
    ul.ztree span.file {
      width: 20px;
      height: 20px;
      display: inline-block;
      background-image: url("../../../../static/img/file_icon.png");
      background-repeat: no-repeat;
      float: left;
      margin: 1px 4px 0 0;
      background-position: 0 -280px;
    }
    </style>
    
    <template>
    	<!--(ztree-?)-->
    	<div class="ztree_content_wrap" v-if='treeDataSource.length>0'>
    		<div class="zTreeDemoBackground left">
    			<ul class="ztree">
    				<ztree-item v-for='(m,i) in treeDataSource' :key='i' :model.sync="m" :num.sync='i' root='0' :nodes.sync='treeDataSource.length' :callback='func' :expandfunc='expand' :cxtmenufunc='contextmenu' :trees.sync='treeDataSource'></ztree-item>
    			</ul>
    		</div>
    	</div>
    </template>
    
    <script>
    import Vue from "vue";
    export default {
      data() {
        return {
          treeDataSource: []
        };
      },
      props: {
        // 树数据
        list: {
          type: Array,
          twoWay: true
        },
        // 点击节点回调
        func: {
          type: Function,
          default: null
        },
        // 点击展开回调
        expand: {
          type: Function,
          default: null
        },
        // 右击事件
        contextmenu: {
          type: Function,
          default: function() {
            //console.log("defalt click contextmenu");
          }
        },
        // 是否展开
        isOpen: {
          type: Boolean,
          twoWay: true,
          default: false
        }
      },
      watch: {
        list: {
          handler: function() {
            // //console.log("value改版", this.list);
            this.initTreeData();
          },
          deep: true
        }
      },
      methods: {
        initTreeData() {
          var tempList = JSON.parse(JSON.stringify(this.list)),
            that = this;
          // //console.log("接收对象渲染")
          // 递归操作,增加删除一些属性。比如: 展开/收起
          var recurrenceFunc = data => {
            data.forEach(m => {
              if (!m.hasOwnProperty("clickNode")) {
                m.clickNode = m.hasOwnProperty("clickNode") ? m.clickNode : false;
              }
    
              m.children = m.children || [];
              if (!m.hasOwnProperty("isFolder")) {
                m.isFolder = m.hasOwnProperty("open") ? m.open : this.isOpen;
              }
    
              if (!m.hasOwnProperty("isExpand")) {
                m.isExpand = m.hasOwnProperty("open") ? m.open : this.isOpen;
              }
              m.loadNode = 0;
              // recurrenceFunc(m.children);
            });
          };
          recurrenceFunc(this.list);
          this.treeDataSource = tempList;
        }
      },
      components: {
        // 组件
        ztreeItem: {
          name: "ztreeItem",
          props: {
            model: {
              type: Object,
              twoWay: true
            },
            num: {
              type: Number,
              twoWay: true
            },
            nodes: {
              type: Number,
              twoWay: true,
              default: 0
            },
            trees: {
              type: Array,
              twoWay: true,
              default: []
            },
            root: {
              type: String,
              twoWay: true
            },
            callback: {
              type: Function
            },
            expandfunc: {
              type: Function
            },
            cxtmenufunc: {
              type: Function
            }
          },
          methods: {
            Func(m) {
              // 查找点击的子节点
              var recurFunc = (data, list) => {
                data.forEach(i => {
                  // 组织Id  类型Id  实例Id
                  if (i.orgId == m.orgId) {
                    i.clickNode = true;
    
                    if (typeof this.callback == "function") {
                      this.callback.call(null, m, list, this.trees);
                    }
                  } else {
                    i.clickNode = false;
                  }
    
                  if (i.children) {
                    recurFunc(i.children, i);
                  }
                });
              };
    
              recurFunc(this.trees, this.trees);
            },
            open(m) {
              //
              m.isExpand = !m.isExpand;
    
              if (typeof this.expandfunc == "function" && m.isExpand) {
                if (m.loadNode != 2) {
                  //
                  this.expandfunc.call(null, m);
                } else {
                  m.isFolder = !m.isFolder;
                }
              } else {
                m.isFolder = !m.isFolder;
              }
            }
          },
          computed: {
            // 给(根 和 子树)赋值不同的样式
            rootClass() {
              var strRootClass = "";
    
              // 根判断
              if (this.root == "0") {
                strRootClass =
                  this.num == 0 && this.model.children.length == 0
                    ? "roots_docu"
                    : this.nodes == 1 ||
                      (this.num == 0 && this.nodes != this.num + 1)
                      ? "root_"
                      : this.nodes == this.num + 1 ? "bottom_" : "center_";
    
                // 子树判断
              } else if (this.root == "1") {
                // //console.log("model:",this.model,"children:",this.model.children)
                strRootClass =
                  this.nodes > 1 &&
                  this.model.children.length > 0 &&
                  this.nodes != this.num + 1
                    ? "center_"
                    : (this.num == 0 && this.nodes > 1) ||
                      this.nodes != this.num + 1
                      ? "center_docu"
                      : (this.nodes == 1 && this.num != 0) ||
                        (this.nodes == this.num + 1 &&
                          this.model.children.length > 0)
                        ? "bottom_"
                        : "bottom_docu";
              }
    
              return strRootClass;
            },
            // 是否有儿子节点
            isChildren() {
              return this.num + 1 != this.nodes;
            },
            // 展开/收起
            prefixClass() {
              var returnChar = "";
              if (this.rootClass.indexOf("docu") == -1) {
                if (this.model.isFolder) {
                  returnChar = "open";
                } else {
                  returnChar = "close";
                }
              }
    
              if (
                this.model.children.length == 0 &&
                this.rootClass.indexOf("docu") == -1
              ) {
                returnChar = "docu";
              }
    
              return returnChar;
            },
            liClassVal() {
              return "level" + this.num;
            },
            spanClassVal() {
              return (
                "button level" +
                this.num +
                " switch " +
                this.rootClass +
                this.prefixClass
              );
            },
            aClassVal() {
              return this.model.clickNode
                ? "level" + this.num + " curSelectedNode"
                : "level" + this.num;
            },
            ulClassVal() {
              return this.isChildren && this.model.children.length > 0
                ? "level" + this.num + " line"
                : "level" + this.num;
            }
          },
          template: `<li :class="liClassVal">
    				<span :class="spanClassVal" @click='open(model)'></span>
    				<a :class="aClassVal" @click='Func(model)' @contextmenu.prevent='cxtmenufunc(model)'>
    				    <span :class="{loadSyncNode:model.loadNode==1}" v-if='model.loadNode==1'></span>
    				    <span :class='model.iconClass' v-show='model.iconClass' v-else></span>
                <el-tooltip popper-class="treetip" effect="dark" :content="model.orgName" placement="top" :open-delay="1000">
                  <span class="node_name">{{model.orgName}}</span>
                </el-tooltip>
    				</a>
    				<ul :class="ulClassVal" v-show='model.isFolder'>
    					<ztree-item v-for="(item,i) in model.children" :key='i' :callback='callback' :expandfunc='expandfunc' :cxtmenufunc='cxtmenufunc' :model.sync="item" :num.sync='i' root='1' :nodes.sync='model.children.length' :trees.sync='trees'></ztree-item>
    				</ul>
          </li>`
          
          
        }
      },
      update() {
        this.initTreeData();
      },
      mounted() {
        Vue.nextTick(() => {
          this.initTreeData();
        });
       
      }
    };
    </script>

    结构简单  但不好写说实话   样式也免费赠送  就是设置一些背景图片啥的 就没了   这个当然有两种方式了 懒加载 和  俗称的PID渲染  先说这么多吧

     

    展开全文
  • 树形结构数据 递归函数 vue 数据结构 let arr = [ { name: '第一级', id:1, children: [ { name: '第二级', id:12, children: [ { name: '第三级', id:13, children...
  • Vue 树形结构

    2020-04-20 23:28:45
    <template> <li> <div @click="toggle"> {{ model.title }} <span v-if="isFolder"> {{ open ? '+' : '-' }} </span> </div> <ul...
  • ant-design-vue树形结构控件的改造

    千次阅读 2020-04-14 12:53:58
    有一个树形结构的菜单管理,与官网ant-design-vue中提供的a-tree不同 图标不同 每条数据hover的时候都有操作按钮 解决方案 第一个问题 这是不修改a-tree的任何样式文件时出现的icon图标,与项目项目要求不符 若要...
  • 基于element+vue树形结构外加多选框

    千次阅读 2018-12-11 17:18:59
    今天有空整理了之前项目中用到的树形结构外加多选框,并实现一定的逻辑,比如全选,单选,全选和单选之间的联动 之前也在网上搜到过有关此功能的实现,于是我也就参考着写了一个,放在了自己的博客里,就当是给自己做了...
  • vue树形结构获取键值

    2019-10-04 10:32:57
    把键值文件放入 引入控件 import { getTypeValue } from '@/api/dict/dictValue/index';   ...el-form-item label="机构名称" placeholder="请选择机构" prop="orgName">... <...
  • 效果展示: 思路: 右边的button用插槽的方式添加 <template> <div class="m-page"> <div class="content"> <div class="menu-data"> <div class="header">.../sp
  • VUE 实现树形结构

    2018-10-08 10:34:01
    vue 树形结构 添加删除节点 返回ID 可同步到服务器 treelist组件
  • 主要介绍了vue实现的树形结构加多选框,结合实例形式分析了在之前递归组件实现vue树形结构的基础之上再加上多选框功能相关操作技巧,需要的朋友可以参考下
  • 主要介绍了vue树形结构样式和功能,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
  • vue tree树形结构仿文件夹目录

    千次阅读 2020-12-24 21:40:10
    vue 树形结构利用vue组件自己调用自己,循环遍历生成树形结构。 组件调用自己时应绑定 name属性 拓展:给组件命名的三大作用 1.允许组件模板递归地调用自身; 2.指定 name 选项的另一个好处是便于调试。有名字的组件...
  • vue tree 树形结构.pdf

    2021-09-14 14:33:44
    vue tree 树形结构.pdf

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,986
精华内容 2,394
关键字:

vue树形结构

vue 订阅