Vue组件化(四)| 小册免费学

181 阅读2分钟

之前我们介绍了两种类型的组件封装,现在我们来说一下另外一种组件,递归组件。这种组件可用于列表展开、树形表格等

递归组件

我们在使用组件时一般都是先使用import导入,然后在components选项中声明,最后在组件中使用;但其实还有一种使用组件的方法,当组件声明了选项name之后就可以使用name调用自身了(声明name时首字母大写),这也是递归组件的原理

但是不可以直接使用,需要有一个限制条件,不然就会调用栈溢出了,比如下面这样

image-20210427215454844

所以递归组件实现的关键在于以下两点:

  • 要给组件设置 name;
  • 要有一个明确的结束条件 我们来实现一个简易的树形组件,用来展开和闭合列表

首先我们来创建一个模板

<template>
  <li>
    <div @click="toggle">
      {{model.title}}
      <span v-if="isFolder">[{{open ? '-' : '+'}}]</span>
    </div>
  </li>
</template>
  • 在外层使用ul包裹,组件内部就是li,一个组件就是一个li选项
  • 当li还有子组件时会显示+-,展开式显示-,关闭时显示+
  • isFolder就是一个计算属性,用来判断有没有子组件
  • 通过toggle事件来控制open的打开和关闭
export default {
  name: "Tree",
  props: {
    model: {
      type: Object,
      required: true,
    },
  },
  data() {
    return { 
      open: false 
    };
  },
  computed: {
    isFolder() {
      return this.model.children && this.model.children.length;
    }
  },
  methods: {
    toggle() {
      if (this.isFolder) {
        this.open = !this.open;
      }
    },
  },
};

我们来添加一下数据来试一下效果(title用于显示,children包含它的子项),绑定的数据需要是一个数组,使用v-for指令将数组每一项绑定给tree组件

<template>
  <ul>
    <tree v-for="(model, index) in treeData" :key="index" :model="model"></tree>
  </ul>
</template>

<script>
	export default {
    data() {
      return {
        treeData: [
        {
          title: '打野',
          children: [
            {
              title: '刺客',
              children: [
                {
                  title: '兰陵王'
                },{
                  title: '李白'
                }
              ]
          // ……省略大段数据代码
      }
    }
  }
</script>

现在的效果是这样的

image-20210427230021328

接下来我们就来注入灵魂,实现组件递归,将tree组件做一下修改

<template>
  <li>
    <div @click="toggle">
      {{model.title}}
      <span v-if="isFolder">[{{open ? '-' : '+'}}]</span>
    </div>
    <ul v-show="open" v-if="isFolder">
      <tree class="item" v-for="model in model.children" :model="model" :key="model.title"></tree>
    </ul>
  </li>
</template>

注意我上面的代码,我用v-if限制了tree的递归,这里一定要注意,不限制会造成调用栈溢出。 然后再看效果

QQ录屏20210427230225

完成,当然这只是粗略版本,这样拿出去肯定是用不了的,还需要拓展功能调整样式 最后谈一谈基础组件封装的一些要求

高质量。一般通俗点说,对外,接口舒适,人性化,语义化。比如,提供size接口,一般意味着,就是元素的大小。对内,逻辑紧凑,要有一定的容错处理,当然,如果是自己用的话,容错处理可以做的比较低一点。数据改变,对应什么行为自己要理清楚 。如果是提供他人使用的话,需要有一份比较详细的使用文档。

本文正在参与「掘金小册免费学啦!」活动, 点击查看活动详情