> For the complete documentation index, see [llms.txt](https://zpliu.gitbook.io/booknote/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://zpliu.gitbook.io/booknote/vue/12-shen-ru-le-jie-zu-jian-hua.md).

# 深入了解组件化

### 1.组件注册

* 组件命名时遵循w3c规范，字母小写包含一个连接符，名字依赖于你想用它来干什么
* **全局注册** ，组件注册后可以在任意Vue实例中使用，但是当你不需要使用其中的一些组件时，会增加用户下载javascripte的量
* **局部注册** ，可以使用js对象先定义组件，在Vue实例对象的components中挂载对应的组件

  ```javascript
  var hello={
    props: ['value'],
    template: `
    <div>
      <input v-bind:value="value" v-on:input="$emit('input', $event.target.value)">  
      <slot></slot>
      </div>
    `
  }

  components:{
              'hello':hello
          }
  ```
* 使用模块系统进行局部注册

  例如存在一个专门存放组件的components目录，里面有三个组件文件componentA 、componentB 、componentC 在componeentC中实验另外两个组件

## 2.props

* 命名 参考官方不赘述 <https://cn.vuejs.org/v2/guide/components-props.html>
* 定义prop属性

  ```javascript
  props: {
    title: String,
    likes: Number,
    isPublished: Boolean,
    commentIds: Array,
    author: Object,
    callback: Function,
    contactsPromise: Promise // or any other constructor
  }
  ```
* prop中的数据流是单向的，父组件的prop会更新子组件
* 非prop的特性，当显式的定义一个prop时，是为了方便与子组件进行交流，但是不能完全的预见组件会被用于什么场景，非prop的特性会被加到根元素上

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

  var hello={
    props: ['value'],
    template: `
    <div>
      <input v-bind:value="value" v-on:input="$emit('input', $event.target.value)">  
      <slot></slot>
      </div>
    `
  }
  //最后根元素div会拥有title属性
  ```
* 合并和替换

  非prop特性会将原有的特性替换或者合并,例如模板中的`type=date`会被非prop特性`type=text`给替换

  `class=datasfdsaf`会和模板中的`class=from-control`合并
* 禁止非prop特性的继承性

  前面说过非prop特性会被跟元素继承，当使用`inheriAttrs:fale`时根元素将不会被根元素继承，同时可以使用`v-bind="$attrs"`将非prop特性继承给任意元素

## 3.自定义事件

* 事件名

  在父组件中的事件名是HTML内容所以大小写不敏感的，子组件中去抛出时就不会被父组件监听到

  ```javascript
  //父组件鉴定myEvent相当于监听myevent事件
  而在子组件使用 $emit('myEvent')就是myEvent事件了，所以父组件和子组件谈的就不是同一个东西了
  ```

## 4.基于文件的组件化

​ 将html标签在文件中定义好

```javascript
;(function(exports){
    const header_template=`<header>        
        </header>`
    const section_template=`<section class="main" v-show="todos.length">

        </section>`
    const footer_template=`<footer class="footer" v-show="todos.length">

            </footer>`
    exports.appheader={
        template:header_template
    }
    exports.appSection={
        section_template
    }
    exports.appfooter={
        footer_template
    }
})(window)
```

在Vue实例中定义局部组件，使用组件文件中定义好的对象，这个对象已经被挂载到window对象上

```javascript
;(function(exports){

exports.app=new Vue({
    el:"#app",
    components:{
        'app-header':appheader,
        'app-section':appSection,
        'app-footer':appfooter
    }
})

})(window)
```

在html文件中使用组件，和引用对应的Vue和组件文件

```markup
    <section class="todoapp" v-cloak id="app">
    <app-header></app-header>
    <app-section></app-section>
    <app-footer></app-footer>
    </section>
    <--!> 文件具有加载顺序 </--!>
    <script type="text/javascript" src="/node_modules/vue/dist/vue.js"></script>
    <script type="text/javascript" src="/component/js/components.js"></script>
    <script type="text/javascript" src="/component/js/app.js"></script>
```

## 5.
