vue 组件分类

vue 组件分类

一. 简介

之所以写这篇文章,是因为前段时间作为面试官,陆陆续续面试了几十个人,其中一个问题就是 "vue 的组件分类都有哪些?" ,令人惊讶的是大多数人都只回答了全局组件局部组件,难道vue的组件就只是这两种吗?其实谈分类,是一定要谈分类标准的,没有分类标准的分类都是耍流氓。以下是个人总结,不喜勿喷。

本文 github 源码地址

二.分类

1.按组件注册方式分类:可以分为全局组件局部组件

全局组件


a. 全局组件注册

Vue.component("my-component-name", {
  /****/
});

b. 使用

<my-component-name></my-component-name>

c. 什么情况下需要将组件注册为全局组件?

一般是一些基础组件,频繁(3 次以上)需要用到的,需要全局注册。比如常用的 dialog 组件,search 组件,toast 组件,message 组件等。

局部组件


a. 局部组件注册

import ComponentA from "./ComponentA.vue";
export default {
  components: {
    ComponentA
  }
  // ...
};

b. 使用

<component-a></component-a>

c. 什么情况下需要将组件注册为局部组件?

一般情况下的组件都应该是局部组件,这样会极大的减少构建应用后的代码体积,但是对于频繁使用的组件就显得麻烦了,所以建议,组件使用频率低,组件比较大的时候注册为局部组件。比如 table 组件,chart 组件等

2.按组件有无自己的状态分类:可以分为函数式(无状态)组件普通(有状态)组件

a. 函数式组件

新建文件

src/components/FunctionComponent/index.vue

functional字段标记该组件是一个函数式组件

函数式组件里面用的是 jsx 的语法

<script>
  import OtherComponent from "./other";
  export default {
    name: "FunctionComponent",
    functional: true,
    components: {
      OtherComponent
    },
    props: {
      title: {
        type: String,
        required: true
      }
    },
    render(h, { props }) {
      const { title } = props;
      return (
        <div>
          <p> 我是函数式组件</p>
          <p>props {title}</p>
          <OtherComponent otherInfo={title} title="我是函数式组件的其他组件" />
        </div>
      );
    }
  };
</script>

src/components/FunctionComponent/other.vue

基于模板的函数式组件 template 标签要标记 functional

<template functional>
  <div>
    {{ props.title }}
    <p>
      otherInfo {{ props.otherInfo }}
    </p>
  </div>
</template>
<script>
  export default {
    functional: true,
    props: {
      title: {
        default: "",
        type: String
      },
      otherInfo: {
        default: "",
        type: String
      }
    }
  };
</script>

b. 使用

import FunctionComponent from "./components/FunctionComponent/index";

export default {
  components: {
    FunctionComponent
  }
};
<function-component title="函数式组件" />

c. 什么情况下需要将组件写为函数式组件?

一般是无状态 (没有响应式数据)的组件可以注册成函数式组件,好像不用函数式组件也可以呀,为啥要注册成函数式组件?

当一个组件是一个函数式组件的时候,它没有管理任何状态,也没有监听任何传递给它的状态,也没有生命周期方法。实际上,它只是一个接受一些 prop 的函数,所以渲染开销也低很多。

3.按组件是否动态分类:可以分为动态组件普通(非动态)组件

a. 动态组件

新建文件

src/components/DynamicComponent/1.vue

<template>
  <div>
    动态组件1
  </div>
</template>

src/components/DynamicComponent/1.vue

<template>
  <div>
    动态组件1
  </div>
</template>

b. 使用

<button @click="toggle('1')">点击切换组件1</button>
<button class="btn" @click="toggle('2')">点击切换组件2</button>
<component :is="currentTabComponent"></component>
import DynamicComponent1 from "./components/DynamicComponent/1";
import DynamicComponent2 from "./components/DynamicComponent/2";
export default {
  components: {
    DynamicComponent1,
    DynamicComponent2
  },
  data() {
    return {
      currentTabComponent: "DynamicComponent1"
    };
  },
  methods: {
    toggle(type) {
      this.currentTabComponent = "DynamicComponent" + type;
    }
  }
};

可能大家见到过最多是这样子的,有没有很熟悉

<button @click="toggle">点击切换组件1</button>
<dynamic-component1 v-if="show" />
<dynamic-component2 v-else />
import DynamicComponent1 from "./components/DynamicComponent/1";
import DynamicComponent2 from "./components/DynamicComponent/2";
export default {
  components: {
    DynamicComponent1,
    DynamicComponent2
  },
  data() {
    return { show: false };
  },
  methods: {
    toggle() {
      this.show = !this.show;
    }
  }
};

c. 什么情况下需要将组件写为动态组件?

一般是是需要组件之间切换的情况下,好像不用动态组件也可以呀,为啥要动态组件?

可能当你写导入 DynamicComponent1 从 1 写到 10 的时候,然后 template 再写 DynamicComponent 10 次的时候,它的好处就出来了。

4.按组件是否异步分类:可以分为异步组件普通(非异步)组件

a.异步组件

在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。为了简化,Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染

新建文件

src/components/AsyncComponent.vue

<template>
  <div>
    <ul>
      <li v-for="item in list" :key="item.name">{{ item.name }}</li>
    </ul>
  </div>
</template>
<script>
  export default {
    name: "AsyncComponents",
    components: {},
    data() {
      return { list: [] };
    },
    created() {
      this.getList();
    },
    methods: {
      getList() {
        setTimeout(() => {
          const data = [
            { name: "你好", time: "2019-01-01 10:10:55" },
            { name: "世界", time: "2012012-01 12:20:00" }
          ];
          this.list = data;
        }, 2000);
      }
    }
  };
</script>

b. 使用

<async-component />
import AsyncComponent from "./components/AsyncComponent";
export default {
  components: {
    AsyncComponent
  }
};

c. 什么情况下需要将组件写为异步组件?

一般是需要从服务器加载数据的组件,且需要多个地方使用的,因为它会把结果缓存起来供未来重渲染。

还有就是大家使用最多的 是在 Vue Router 里使用,异步组件结合 Webpack 的代码分割功能,可以轻松实现路由组件的懒加载。

5.按组件是否循环引用分类:可以分为递归组件普通(非递归)组件

a.递归组件

组件是可以在它们自己的模板中调用自身的。不过它们只能通过 name 选项来做这件事。

新建文件

src/components/RecursiveComponent.vue

<template>
  <div>
    <ul>
      <li v-for="item in list" :key="item.name">
        <span>{{ item.name }}</span>
        <recursive-component v-if="item.children" :list="item.children" />
      </li>
    </ul>
  </div>
</template>
<script>
  export default {
    name: "RecursiveComponent",
    props: {
      list: {
        default: () => [],
        type: Array
      }
    }
  };
</script>

b. 使用

<recursive-component :list="list" />
import RecursiveComponent from "./components/RecursiveComponent";
export default {
  components: {
    RecursiveComponent
  },
  data() {
    return {
      list: [
        {
          name: "1",
          children: [
            {
              name: "1-1"
            },
            {
              name: "1-2",
              children: [
                {
                  name: "1-2-1"
                },
                {
                  name: "1-2-2"
                }
              ]
            }
          ]
        },
        {
          name: "2",
          children: [
            {
              name: "2-1",
              children: [
                {
                  name: "2-1-1"
                },
                {
                  name: "2-1-2",
                  children: [
                    {
                      name: "2-1-2-1"
                    },
                    {
                      name: "2-1-2-2"
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    };
  }
};

c. 什么情况下需要将组件写为递归组件?

一般是组件需要调用自身的时候,比如树组件,侧边栏路由组件等

三.总结

分类标准分类 1分类 2
注册方式全局组件局部组件
有无自己的状态函数式(无状态)组件普通(有状态)组件
是否动态动态组件普通(非动态)组件
是否异步异步组件普通(非异步)组件
是否循环引用递归组件普通(非递归)组件

参考链接

1.https://cn.vuejs.org/

2.https://router.vuejs.org/zh/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaofei0627

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值