Vue如何实现组件的复用和扩展?

1. 组件复用

Vue.js是一个组件化的框架,组件到组件之间的复用可以说是非常方便了。我们可以将一个组件封装好后,在另一个组件中直接引用。这种方式不仅代码复用率高,而且方便维护。

1.1 全局注册

在Vue中,我们可以通过Vue.component()函数进行全局组件注册,使用Vue.component()语法可以使得组件在一个Vue实例内的所有组件中都可以使用,实现组件的复用。

下面是一个注册Header组件的实例代码:


Vue.component('my-header', {
  template: '<div>Header Component Here.</div>'
})

上面的例子中,我们定义了一个名为'my-header'的组件,并且将模板里面的内容渲染为Hello World。

使用该组件时,只需要在我们的Vue实例中调用这个组件即可。


var app = new Vue({
  el: '#app',
  template: '<my-header></my-header>'
})

在模板中,我们使用my-header标签来引用我们之前注册的组件,这样就可以在模板中使用我们的组件了。

1.2 局部注册

局部注册是指只在当前组件内注册,其他组件无法使用该组件。通常情况下,我们会在组件内使用局部组件注册,因为组件只在该组件中使用,不需要全局复用。

下面是一个使用localHeader组件的实例代码:


Vue.component('my-component', {
  components: {
    'local-header': {
      template: '<div>I am a local header</div>'
    }
  },
  template: '<local-header></local-header>'
})

上面的例子中,我们在my-component组件中注册了一个局部组件local-header。

2. 组件扩展

组件扩展是指在一个已有组件的基础上,对该组件进行功能上的扩展。

Vue.js提供了一种非常方便的方式来做到组件的扩展。它提供了一个extends属性,可以用来重新定义组件的选项,所有与原始选项相同的选项将被覆盖。

下面的例子中,我们可以在已有的my-header组件基础上进行扩展:


Vue.component('my-header', {
  props: ['title'],
  template: '<div>{{ title }}</div>'
})
Vue.component('header-extended', {
  extends: Vue.component('my-header'),
  data() {
    return {
      subTitle: 'This is sub title'
    }
  },
  computed: {
    extendedTitle() {
      return this.title + ' - ' + this.subTitle
    }
  },
  template: '<div>{{ extendedTitle }}</div>'
})

上面的代码中,我们创建了两个组件,一个是my-header,一个是header-extended,header-extended通过Vue.component()方法对my-header进行了扩展,增加了一个subTitle和extendedTitle属性,这两个属性覆盖了my-header中的同名属性,从而实现了对my-header的扩展。

2.1 混入(mixins)

除了使用extends属性来进行组件扩展,Vue还提供了一种更灵活的方式来扩展一个组件,它就是混入。

混入是指将多个对象合并成为一个,这样做的优点在于,可以在多个组件中复用同一段代码,从而提高代码效率。

下面是一个混入对象的例子:


var myMixin = {
  created() {
    this.testMixin()
  },
  methods: {
    testMixin() {
      console.log('I am a mixin.');
    }
  }
}

上面的代码中,我们定义了一个mixin对象,它包含了一个created钩子函数和一个testMixin方法。

下面的例子中,我们将上面的mixin对象混入到myHeader组件中:


Vue.component('my-header', {
  mixIns: [myMixin],
  template: '<div>Hello World</div>'
})

这样,在myHeader组件被创建的时候,我们在控制台就可以看到'I am a mixin.'这条输出了。

2.2 slot插槽

在Vue.js中,可以使用插槽(slot)来扩展组件的功能,插槽可以让我们在组件中定义一些不确定的内容,并将其暴露出去,让用户根据需要进行填充。

下面的例子中,我们创建了一个myDialog组件,它包含了一个title和一个body插槽:


Vue.component('my-dialog', {
  template: `
  <div class="my-dialog">
    <div class="my-dialog__header">
        {{title}}
    </div>
    <div class="my-dialog__body">
        <slot name="body"></slot>
    </div>
  </div>
  `,
  props: ['title']
})

上面的代码中,我们通过插槽来让用户在myDialog组件中定义body数据,并使用slot元素来渲染body插槽。

下面是我们在Vue实例中使用myDialog的例子代码:


<my-dialog title="Dialog Test">
  This is Dialog Body
</my-dialog>

在上面的代码中,我们可以看到,我们使用myDialog组件的时候,将需要填充到body插槽的内容直接写在myDialog的标签之间,这样Vue会将其渲染进组件中。

3. 总结

通过上面的内容,我们了解了Vue.js组件的复用和扩展。

通过全局注册和局部注册,我们可以让一个组件在全局或局部范围内进行复用。

通过extends属性和mixin对象,我们可以对一个已有组件进行功能上的扩展。

通过插槽的使用,我们可以在组件中定义不确定的内容,并暴露给用户进行填充。

Vue.js的组件化,让我们的开发效率大大提高了。当我们的应用越来越庞大时,组件化的优势将更加明显。