# 页面组件化

## 1. 基本知识

* :warning:组件的定义使用Vue对象的component方法进行定义，并且组件必须在实例对象被挂载之前定义好，这种方式也被称为**组件的全局注册**

  ```javascript
  Vue.component('hello', {
      data: function () {
      return {
        count: 0
      }
    },
    template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
  })
  ```
* 组件中的data属性是一个函数，函数返回一个数据对象，里面存储了数据，因而使得组件能够实现复用，而不会相互影响

  ```javascript
      data: function(){
          return {
              count:0
          }
      }
  ```
* `props`向组件中传递数据

  在组件注册时，提前设置好自定义属性，通过Vue实例将数据传递给组件属性，从而使得组件内部获得外部的数据

  ```javascript
  //注册组件
  Vue.component('blog-post', {
    props: ['title'],
    template: '<h3>{{ title }}</h3>'
  })
  //vue实例数据传递数据
  <blog-post :title="someTitle"></blog-post>
  ```
* 组件中必须包含单个根元素

  但是当根元素内包含的元素越来越复杂的时候，为每一个元素定义一个prop会变得很麻烦；这样的话可以重构这个组件

  在构建模板字符串时，使用到了`反引号`，这在IE下没有别支持，可以使用工具将模板字符串放在同一行

  \`\`\`javascript //将对象赋值给post属性

  \<blog-post v-for="post in posts" v-bind:key="post.id" v-bind:post="post"

  > \</blog-post>

//直接使用post对象中的值 Vue.component('blog-post', { props: \['post'], template: `<div class="blog-post"> <h3>{{ post.title }}</h3> <div v-html="post.content"></div> </div>` })

````
+ 监听子组件的事件



  子组件调用$emit方法触发事件名字，在父组件中使用v-on监听事件的发生从而做出响应

  ```javascript
  Vue.component('blog-post', {
    props: ['post'],
    template: `
      <div class="blog-post">
        <h3>{{ post.title }}</h3>
        <div v-html="post.content"></div>
        <button v-on:click="$emit('enlarhe-txt')"> //子组件中触发事件
          Enlarge text
        </button>
      </div>
    `
  })

  //在父组件组件放置监听事件
  <blog-post v-on:enlarge-text="postFontSize += 0.1"></blog-post>
````

* 子组件事件传递值

  当$emit函数中传递第二个值的时候，在父组件中可以使用$event访问到这个被子组件抛出的值

  `v-on:click=$emit('enlage-txt ,0')`

  `v-on:enlarge-txt='some +=$event'`

  * 当传递到父组件是对应的函数来处理子组件的事件的时候，这个值将会被作为父组件函数的第一个参
* 在组件中使用v-model
* 首先在父组件中定义好value属性，用于v-model绑定根节点的数据
  * 在子组件中使用v-bind将父节点的value属性绑定到input的value属性上
* 在子组件中监听input事件，将值 抛出给父组件

  &#x20; v-model是自动的将值绑定到value属性上的
* 插槽

  通过slot标签向模板中传递内容

  ```javascript
  template: `
    <div>
    <input v-bind:value="value" v-on:input="$emit('input', $event.target.value)">

    <slot></slot>
      </div>
  `
  ```
* 动态的组件

  在vue中通过使用component标签，加上is属性可以选择动态的使用哪一个属性

  这里要注意的是is属性绑定的是vue实例对象中的数据，因此当数据改变时，组件也就改变了这就是所谓的动态

  ```javascript
    <component v-bind:is="currentComponent" v-model="count">{{count}}</component>
  ```
