好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

手写Vue内置组件component的实现示例

最近在复习Vue的源码,今天带大家手写实现一下Vue内置组件component,比较简单,最近面试有被问到。

前言

Vue 大家都很熟悉,除了原生的组件,其自己也封装了一下内置组件,比如 component , transition , keep-alive 等等。

component 算是用的比较多的了,当我们遇到需要根据不同条件显示不同组件的时候,一般都是用 component 来实现。当然你也可以 v-if,v-else-if,v-else ,就显的比较笨了。

大家如果没用过,可以先自己尝试一下这个 component 组件。最主要的就是它有一个 is 属性,你给is赋予什么组件名,它就渲染什么组件。

内置组件component的使用

我写一个小 demo 演示一下。
先随意的写三个组件, A , B , C 。

组件内容就是 aaaa , bbbb , cccc ,方便我们辨认当然渲染的是哪个组件。

然后集体引入,挂载。

视图内容大概这样写,需求就是,准备三个按钮,点击哪个按钮就显示哪个组件。

    <div>
      <button @click="changeComp('A')">显示A</button>
      <button @click="changeComp('B')">显示B</button>
      <button @click="changeComp('C')">显示C</button>
    </div>
    <component :is="compList"></component>

compList 提前声明好,默认是 A 组件。

  data() {
    return {
      compList: 'A'
    };
  },

changeComp 函数内容如下:

  methods: {
    changeComp(comp) {
      this.compList = comp;
    },
  }

OK,这就完事了,大家可以自己试一下,是可以完成既定的需求的。

component组件的原理分析

我们今天的任务是,了解内置组件 component 的原理,并手写实现一个。

那么 component 的实现原理是怎么样的呢,这个就需要牵扯一块比较大的知识链了,也是 Vue 的核心内容。关于 Vue 的 虚拟DOM 以及模板编译的部分内容。

简单来说, Vue 内部实现了一个 虚拟DOM 来妥善解决 原生DOM 的性能问题。

虚拟DOM与原生DOM

比如我们当前需要插入 1000 个 DOM 节点,如果是 原生DOM 来做的话,就是扎扎实实的,一个个操作,改变 DOM , DOM 需要被改变 1000 次,这对于性能是极大的损耗,造成很多的问题。

虚拟DOM 的原理就是,先在框架内部用对象模拟一下 原生DOM 的形态,记录你这 1000 次的 DOM 操作,最后将 DOM 被操作 1000 次后的形态赋给 原生DOM 。这样就能极大的优化大量 DOM 操作带来的负面影响。

然后再来思考一下,我们平时写的 .vue 文件,其实跟原生写法是有区别的,无论是 HTML 、 JS 还是 CSS ,在编写阶段有做了些许的改动,这样做有助于提高我们的编写效率。但是浏览器是只认原生的 HTML 、 CSS 和 JS 的,所以我们编写的组件内容,其实只是一个 template 模板,需要进行编译转换为原生的 DOM 才能渲染到浏览器上。

而 componet 组件其实就是内部做了这个事情,将你传入的组件, 先转换为 虚拟DOM ,然后渲染为真实 DOM ,展示到视图上。

render函数的使用

这里面就涉及到一个知识点了,关于 render 函数的使用,具体的内容大家可以去 Vue 文档详细了解一下 render 函数。可能大家日常开发用的比较少,涉及一些偏底层的东西时才会遇到。

我这里只介绍 render 函数做的事情。
它的形态大概是这个样式。

render(h) {
    // return h('A');
    return h('div', '6666');
},

render 函数接收一个参数,比如叫它 h , h 也是一个函数,它的作用就是将传入的内容构建为 虚拟DOM ,这个传入的内容支持原生的写法,也支持 Vue 组件。

比如我代码里给出的, h('div', '6666') , h 函数就会生成一个 div 组件,文本内容是 666 。被注释掉的,就是传入 Vue 中自己的写的组件名字为 A ,同样支持。

但是 h 函数仅仅只是将传入的内容,生成 虚拟DOM ,不是真实的 原生DOM ,然后将它 return 出去, render 函数才会将这个 虚拟DOM 渲染成为 真实DOM 。

上述关于 render 函数的内容不知道大家是否理解,可以去 Vue 官方文档里,详细看一下,然后自己写写 demo 体验一下, render 函数算是 Vue 进阶中比较重要的内容了。

所以,话说回来,知道了 render 函数这个东西,我们就能够比较好的实现 component 这个内置组件了。 component 组件会接收一个属性 is , is 的值就是我们要渲染的组件。 component 组件的内容其实就是进行了 Vue组件 => 虚拟DOM => 真实DOM ,渲染视图,其实就通过 render 函数实现就可以。

尝试手写实现component

话不多说,我们试一下。

因为组件内容比较少,所以我们直接使用 Vue.component 来编写组件内容。

Vue.component("myComponent", {
  props: ["is"],
  render(h) {
    return h(this.is);
  },
});

其实核心代码就上面这几行,组件名字是 myComponent , props 的作用就是指定组件要接收的参数 is 。然后编写一下 render 函数,因为是渲染 Vue 组件,所以直接 return h(this.is) 就可以。

将这段代码写在 JS 里,然后就可以使用了。记得要 import Vue from 'vue' 来引入 Vue ,因为我们是通过 Vue.component 来编写组件的。

下面我们试一试,这个 myComponent 是否有用。

    <div>
      <button @click="changeComp('A')">显示A</button>
      <button @click="changeComp('B')">显示B</button>
      <button @click="changeComp('C')">显示C</button>
    </div>
    <component :is="compList"></component>
    <my-component :is="compList"></my-component>

实际操作后可以发现,我们自己写的 myComponent 和 Vue 内置的 component 效果是一模一样的,大家自己也可以试一下。

完整代码:

<template>
  <div>
    <div>
      <button @click="changeComp('A')">显示A</button>
      <button @click="changeComp('B')">显示B</button>
      <button @click="changeComp('C')">显示C</button>
    </div>
    <component :is="compList"></component>
    <my-component :is="compList"></my-component>
  </div>
</template>

<script>
import Vue from "vue";
import A from "components/A.vue";
import B from "components/B.vue";
import C from "components/C.vue";

Vue.component("myComponent", {
  props: ["is"],
  render(h) {
    return h(this.is);
  },
});
export default {
  components: {
    A,
    B,
    C,
  },
  data() {
    return {
      compList: 'A'
    };
  },
  methods: {
    changeComp(comp) {
      this.compList = comp;
    },
  },
};
</script>

<style scoped>

</style>

总结

今天的内容是带着大家手写实现 Vue 的内置组件 component ,在尝试实现某一个东西的时候,就需要先思考它的作用以及内部原理。手写 component 的过程比较简单,但是涉及到了很多 Vue 的原理性知识点,比如虚拟DOM、render函数、模板编译等。

到此这篇关于手写Vue内置组件component的实现示例的文章就介绍到这了,更多相关Vue内置组件component内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

查看更多关于手写Vue内置组件component的实现示例的详细内容...

  阅读:28次