一、组件名
自定义组件的名称强烈推荐遵循W3C规范中的方式:字母全小写且必须包含一个连字符。
二、全局注册和局部注册的区别
- 全局注册
Vue.component进行注册。全局注册的可以在任何创建的实例中引用。全局注册往往是不够理想的,比如你使用webpack这样的构建系统,全局注册所有的组件意味着即便你不再使用一个组件了,
它仍然会被包含在你最终的构建结果中。这就造成用户的下载JavaScript无谓的增加。 - 局部注册
局部注册可以通过一个普通的对象来定义。 
var componentA = {};
var componentB = {};
var componentC = {};
new Vue({
    el: '#app',
    components:{
        'component-a': componentA,
        'component-b': componentB
    }
    //components对象中的‘component-a’是自定义元素的名字,‘component-b’是这个组件的选项对象。
})
 
注意:局部注册的组件在其子组件中不可用,如果希望能用,则要这样做:
var componentA = {};
var componentB = new Vue({
    el: "#aa",
    components:{
        'component-a':'componentA'
    }
})
 
三、可以通过webpack等工具来实现组件的注册
- 在模块系统中可以通过import和export实现局部注册
如果你使用了Babel和webpack这样的模块系统,那么可以建立一个components目录, 并将每个组件放置在其各自的文件中
你在局部注册之前,需要导入每个你想使用的组件。 
import ComponentA from './ComponentA';
import ComponentC from './ComponnetC';
export default {
    components: {
        componentA,
        componentC
    }
}
//现在componentA和componentC都可以在这个组件中使用了。
 
- 基础组件的自动化全局注册
有一些组件可能只包含一个按钮或者输入框,这种称为基础组件,想要一次性局部引用这些组件显得有点繁琐。所以可以在main.js入口文件中,可以进行自动化全局注册。 
import Vue from 'vue'
import upperFirst from 'lodash/upperFirst'
import camelCase from 'lodash/camelCase'
const requireComponent = require.context(
  // 其组件目录的相对路径
  './components',
  // 是否查询其子目录
  false,
  // 匹配基础组件文件名的正则表达式
  /Base[A-Z]\w+\.(vue|js)$/
)
requireComponent.keys().forEach(fileName => {
  // 获取组件配置
  const componentConfig = requireComponent(fileName)
  // 获取组件的 PascalCase 命名
  const componentName = upperFirst(
    camelCase(
      // 剥去文件名开头的 `./` 和结尾的扩展名
      fileName.replace(/^\.\/(.*)\.\w+$/, '$1')
    )
  )
  // 全局注册组件
  Vue.component(
    componentName,
    // 如果这个组件选项是通过 `export default` 导出的,
    // 那么就会优先使用 `.default`,
    // 否则回退到使用模块的根。
    componentConfig.default || componentConfig
  )
})
 
四、Prop的类型
一般我们在使用prop的时候,就是在注册组件的时候设置prop,prop通常的类型是字符串数组。
prop: ['dd','fffe','age']
 
但是通常自己希望每个prop都有指定的值类型。你可以以对象形式列出prop,对应的是prop各自的名称和值。
props: {
  title: String,
  likes: Number,
  isPublished: Boolean,
  commentIds: Array,
  author: Object
}
 
这样如果在遇到错误的类型时,浏览器会在控制台打印出错误。prop可以传递字符串、数字、布尔值、数组、对象、一个对象的所有属性
五、Prop验证
为了定制prop的验证方式,你可以为props中的值提供一个带有验证需求的对象,而不是一个字符串数组。
Vue.component('my-component',{
	props:{
		//基础类型检查 (null 匹配任何类型)
		propA: Number,
		//多个可能的类型
		propB: [String,Number],
		//必填的字符串
		propC: {
			type: String,
			require:true
		},
		//默认的数字
		propD: {
			type: Number,
			default: 100
		},
		//带有默认值的对象
		propE: {
			type:Object,
			default:function(){
				//对象或数组默认值必须从一个工厂函数获取
				return {
					message:'hello'
				}
			}
		},
		//自定义验证函数
		propF:{
			validator: function (value){
				//这个值必须匹配下列字符串中的一个
				return ["success,warning,danger"].indexOf(value) !== -1;
			}
		}
	}
})
 
这些prop验证都是在新实例创建之前,所以实例的属性在default或validator函数中是不可用的。
六、禁用特性继承
如果你不希望子组件的分元素继承特性,可以在组件的选项中设置inheritAttrs: false.
Vue.component('base-input', {
  inheritAttrs: false,
  props: ['label', 'value'],
  template: `
    <label>
      {{ label }}
      <input
        v-bind="$attrs"
        v-bind:value="value"
        v-on:input="$emit('input', $event.target.value)"
      >
    </label>
  `
})
<base-input
  v-model="username"
  class="username-input"
  placeholder="Enter your username"
></base-input>
					