# 深入了解组件化

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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://zpliu.gitbook.io/booknote/vue/12-shen-ru-le-jie-zu-jian-hua.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
