思路:通过递归自我调用,实现多级tree

<template>
  <div class="tree-box">
    <div v-for="(item, index) of list" :key="index" class="item border-top">
      {{item.title}}
      <div v-if="item.children">
        <tree-list :list="item.children" v-bind="$attrs" v-on="$listeners"></tree-list>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name:'TreeList',
  props:{
    list:{
      type: Array,
      default:function(){
        return [
          {title:'1级',children:[
            {title:'1.1级'},
            {title:'1.2级'},
            {title:'1.3级'}
          ]},
          {title:'2级',children:[
            {title:'2.1级',children:[
              {title:'2.1.1级'},
              {title:'2.1.2级'},
              {title:'2.1.3级'},
            ]},
            {title:'2.2级'},
            {title:'2.3级'}
          ]}
        ]
      }
    }
  },
  data(){
    return {
      
    }
  }
}
</script>

<style lang="scss" scoped>
.tree-box{
  margin:20px auto;
}
.item{
  padding:10px;
}
</style>

关键属性解释:

1.v-bind="$attrs"

当一个组件没有声明任何prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。

简单点讲就是:子组件包含了所有父组件上设置的属性(除了class 和 style 以及被prop识别的属性)。

 

2.v-on="$listeners"

包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。
简单点讲就是:它是一个对象,里面包含了作用在这个组件上所有的监听器(监听事件),可以通过 v-on="$listeners" 将事件监听指向这个组件内的子元素(包括内部的子组件)。

 

3.inheritAttrs

该属性在子组件中定义:

Vue.component("Child1", {
        inheritAttrs: true,
        props: ["pChild1"],
        template: `
        <p>in child1:</p>
        `,
        mounted: function() {
          this.$emit("test1");
        }
      });

默认情况下父作用域的不被认作 props 的特性绑定 (attribute bindings) 将会“回退”且作为普通的 HTML 特性应用在子组件的根元素上。当撰写包裹一个目标元素或另一个组件的组件时,这可能不会总是符合预期行为。通过设置 inheritAttrsfalse,这些默认行为将会被去掉。而通过 (同样是 2.4 新增的) 实例属性 $attrs 可以让这些特性生效,且可以通过 v-bind 显性的绑定到非根元素上。
注意:这个选项不影响 class 和 style 绑定。

关于$attr,$linsteners,inheritAttrs这三个属性,详情可查看 https://www.jianshu.com/p/a388d38f8c69

 

拓展:给组件命名的三大作用

1.允许组件模板递归地调用自身;

2.指定 name 选项的另一个好处是便于调试。有名字的组件有更友好的警告信息。另外,当在有 vue-devtools,未命名组件将显示成 <AnonymousComponent>,这很没有语义

3.可提供给 keep-alive 的 include 和 exclude 作为参数选项;

Logo

前往低代码交流专区

更多推荐