# 全局组件

在大型应用开发的时候,页面可以划分成很多部分。往往不同的页面,也会有相同的部分。例如可能会有相同的头部导航。

但是如果每个页面都独自开发,这无疑增加了我们开发的成本。所以我们会把页面的不同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发。

# 定义全局组件

我们通过 Vue 的 Vue.component() 方法来定义一个全局组件。

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>

<script type="text/javascript">
  /*
   * 定义全局组件,两个参数:
   * 1. 组件名称
   * 2. 组件参数
   **/
  Vue.component("counter", {
    template: `
      <button v-on:click="count++">
        你点了我 {{ count }} 次,我记住了.
      </button>
    `,
    data () {
      return {
        count: 0
      }
    }
  });

  ...

</script>

组件其实也是一个 Vue 实例,组件也会有:datamethods、生命周期函数等。不过它是一个特殊的 Vue 实例:

  • 由于组件不是与页面元素绑定的,因此它『没有 el 属性』;

  • 组件的渲染需要 html 模板,所以增加了 template 属性,值就是 HTML 模板;如果 html 模板内容过多,可以使用『反单引号』替换『单引号』,以便换行。

  • data 必须是一个函数,不再是一个对象。

定义组件有 2 处值得注意的地方:

  1. (现阶段)组件的命名使用全小写。如果涉及多个单词,可使用『串行命名法』:xxx-yyy-zzz

  2. 组件中只能有一个元素。如果,你的组件需要有多个元素,那么你要将它们『收拢』在同一个元素下。这个用于『收拢』多个元素的元素被称为组件的根元素。

# 使用全局组件

<div id="app">
  <counter></counter> <!-- 使用定义好的组件 -->
</div>

<script type="text/javascript">
  // 这里是全局组件的定义
  ...

  new Vue({
    el:"#app"
  })
</script>

效果:

component-1


在任何一个被 Vue 托管的元素中,你都可以使用你所定义的全局组件。

<div id="xxx"> <counter></counter> </div>
<div id="yyy"> <counter></counter> </div>
<div id="zzz"> <counter></counter> </div>
<div> <counter></counter> </div> <!-- 注意这个 -->


<script type="text/javascript">
  // 这里是全局组件的定义
  // ...

  new Vue({
    el:"#xxx"
  });
  new Vue({
    el:"#yyy"
  });
  new Vue({
    el:"#zzz"
  });

</script>

另外,定义好的组件,可以任意复用多次:

<div id="app">
  <!--使用定义好的全局组件-->
  <counter></counter>
  <counter></counter>
  <counter></counter>
</div>

效果:

component-2

你会发现每个组件互不干扰,都有自己的 count 值。怎么实现的?

组件的 data 属性必须是函数

组件的 data 属性必须是函数

组件的 data 属性必须是函数

当我们定义这个 <counter> 组件时,它的 data 并不是像这样直接提供一个对象:

// 标准错误答案,标准错误答案,标准错误答案
data: {
  count: 0
}

取而代之的是,一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝。

『罗嗦的』写法如下:

data: function () {
  return {
    count: 0
  }
}

通常简写成:

data() {
  return {
    count: 0
  }
}

如果 Vue 没有这条规则,点击一个按钮就会影响到其它所有实例!