# 页面组件化

## 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>
    ```
