Vue组件知识详解

组件概念

一个完整的网页是复杂的,如果将其作为一个整体来进行开发,将会遇到下面的困难

  • 代码凌乱臃肿
  • 不易协作
  • 难以复用

vue推荐使用一种更加精细的控制方案——组件化开发

所谓组件化,即把一个页面中区域功能细分,每一个区域成为一个组件,每个组件包含:

  • 功能(JS代码)
  • 内容(模板代码)
  • 样式(CSS代码)

由于没有构建工具的支撑,CSS代码暂时无法放到组件中

组件开发

创建组件

组件是根据一个普通的配置对象创建的,所以要开发一个组件,只需要写一个配置对象即可

该配置对象和vue实例的配置是几乎一样

//组件配置对象
var myTest = {
  data(){
    return {
      // ...
    }
  },
  computed:{
    //...
  },
  methods:{
    //...
  },
  template: `....`
}

值得注意的是,组件配置对象和vue实例有以下几点差异:

  • el
  • data必须是一个函数,该函数返回的对象作为数据
  • 由于没有el配置,组件的模板必须定义在template

使用组件

使用组件分为两步:注册组件应用组件

注册组件:让组件可以在模板中使用

应用组件:具体的在模板中使用组件

注册组件

注册组件分为两种方式,一种是全局注册,一种是局部注册

  1. 全局注册

一旦全局注册了一个组件,整个应用中任何地方都可以使用该组件

全局注册的方式是:

// 参数1:组件名称,将来在模板中使用组件时,会使用该名称
// 参数2:组件配置对象
// 该代码运行后,即可在模板中使用组件
Vue.component('my-test', myTest)

在模板中,可以使用组件了

<my-test />
<!-- 或 -->
<my-test></my-test>

但在一些工程化的大型项目中,很多组件都不需要全局使用。
比如一个登录组件,只有在登录的相关页面中使用,如果全局注册,将导致构建工具无法优化打包
因此,除非组件特别通用,否则不建议使用全局注册

  1. 局部注册

局部注册就是哪里要用到组件,就在哪里注册

局部注册的方式是,在要使用组件的组件或实例中加入一个配置:

// 这是另一个要使用my-test的组件
var otherTest = {
  components:{
    // 属性名为组件名称,模板中将使用该名称
    // 属性值为组件配置对象
    "my-test": myTest
  },
  template: `
    <div>
      <!-- 该组件的其他内容 -->
      <my-test></my-test>
    </div>
  `;
}

应用组件

在模板中使用组件特别简单,把组件名当作HTML元素名使用即可。

但要注意以下几点:

  1. 组件必须有结束

组件可以自结束,也可以用结束标记结束,但必须要有结束

下面的组件使用是错误的:

<my-test>
  1. 组件的命名

无论你使用哪种方式注册组件,组件的命名需要遵循规范。

组件可以使用kebab-case 短横线命名法,也可以使用PascalCase 大驼峰命名法

下面两种命名均是可以的

var otherTest = {
  components:{
    "my-test": myTest,  // 方式1
    MyTest: myTest //方式2
  }
}

使用PascalCase方式命名还有一个额外的好处,即可以在模板中使用两种组件名

var otherTest = {
  components:{
    MyTest: myTest
  }
}

模板中:

<!-- 可用 -->
<my-test />
<MyTest />

因此,在使用组件时,为了方便,往往使用以下代码:

var MyTest = {
  //组件配置
}

var OtherTest = {
  components:{
    MyTest// ES6速写属性
  }
}

组件树

一个组件创建好后,往往会在各种地方使用它。它可能多次出现在vue实例中,也可能出现在其他组件中。

于是就形成了一个组件树

向组件传递数据

大部分组件要完成自身的功能,都需要一些额外的信息

比如一个头像组件,需要告诉它头像的地址,这就需要在使用组件时向组件传递数据

传递数据的方式有很多种,最常见的一种是使用组件属性 component props

首先在组件中申明可以接收哪些属性:

var MyTest = {
  props:["p1", "p2", "p3"],
  // 和vue实例一样,使用组件时也会创建组件的实例
  // 而组件的属性会被提取到组件实例中,因此可以在模板中使用
  template: `
    <div>
      {{p1}}, {{p2}}, {{p3}}
    </div>
  `
}

在使用组件时,向其传递属性:

var OtherTest = {
  components: {
    MyTest
  },
  data(){
    return {
      a:1
    }
  },
  template: `
    <my-test :p1="a" :p2="2" p3="3"/>
  `
}

注意:在组件中,属性是只读的,绝不可以更改,这叫做单向数据流

组件实例的生命周期

当我们使用组件时<my-test />,会创建一个组件的实例,类似于vue实例,每个实例都有明确的生命周期
在这里插入图片描述

在生命周期的各个阶段,会触发调用一些函数,这些函数被称为生命周期钩子函数

最常用的两个钩子函数:createdmounted

  1. created

created函数发生在注入之后、模板编译之前,此时,组件还没有呈现界面

如果有些数据需要经过某些计算得到,可以在这里进行更改,届时,在编译中就会直接应用新的数据

但要注意,由于还未呈现界面,如果在这里使用了特别耗时的计算,将导致长时间的白屏

  1. mounted

mounted函数发生在挂载之后,此时页面已经呈现,在这里,可以用传统方案获取到dom,尽管不太常见

如果某些数据在一开始就需要更新,同时又特别耗时,建议放到mounted中

关于异步代码

如果某些组件一开始时要执行一些异步代码(如ajax),createdmounted均可,效果差别不大

因为由于事件循环的机制,会导致异步代码最终都会在挂载完后调用

但如果异步代码需要特别长时间的准备(与很多因素有关),则建议放置到mounted中

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章