Vue组件深入了解(组件注册和Prop)

一、组件名

自定义组件的名称强烈推荐遵循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>
posted @ 2018-11-06 17:45  sminocence  阅读(1442)  评论(0编辑  收藏  举报