9.vue2-组件注册,prop,插槽

Author: vanessa
Date: 2018/06/19

1.组件命名

使用小写,单词中间加横线,如:<my-input></my-input>

2.注册

a.全局注册

Vue.component('my-component-name', {
  // ... 选项 ...
})

b.局部注册,components这个属性一定是复数

var ComponentA = { 
	
}
new Vue({
  el: '#app'
  components: {
    'component-a': ComponentA,
    'component-b': ComponentB
  }
})

3.prop内容

a.html对大小写不敏感,大写都会转化为小写,所以prop中大写会被转化为小写加横线,
props一般以字符串数组对形式展示,但是可以用对象表示,指定每个变量对类型,同时可以添加一些验证

props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
props: {
  title: String,
  likes: Number,
  isPublished: Boolean,
  commentIds: Array,
  author: Object
}
Vue.component('my-component', {
  props: {
    // 基础的类型检查 (`null` 匹配任何类型)
    propA: Number,
    // 多个可能的类型
    propB: [String, Number],
    // 必填的字符串
    propC: {
      type: String,
      required: 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
      }
    }
  }
})

b.传递对值可以是动态对也可是静态的,传递的值可以是数子,字符串,布尔,数组,对象

<blog-post v-bind:title="post.title"></blog-post>

c.单向数据流,父级的改变会单向流动到子级,不能在子组件中改变prop的值
c1.子组件中使用父级的prop传递来的数据,最好在子组件的data中定义一个变量,或者定义一个计算属性
c2.对象和数组是通过引用传入的,子组件中改变会影响父组件的值

ps:使用动态绑定的数据,必须是前面加v-bind后面数据加打括号
:my-object="{user}"

4.属性合并和替换

绝大多少属性会父组件中定义的属性会替换掉子组件中的,class和style会父子间进行合并,追加到子组件的class后面

<bootstrap-date-input>的模版是这样的
<input type="date" class="form-control">
<bootstrap-date-input type="text" class="active"></bootstrap-date-input>
子组件中type属性会被替换成text,class将会进行合并变成  form-control active

ps:禁用特性继承,将放弃父级中的属性

Vue.component('my-component', {
  inheritAttrs: false,
  // ...
})

可以使用$attrs在子组件中使用父组件的属性,通过inheritAttrs:false禁止向父级继承属性,通过v-bind="$attrs",将父级的属性绑定到子组件的input标签上

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" data-ss="aaaa"></base-input>

4.具名插槽

<base-layout>
  <h1 slot="header">Here might be a page title</h1>

  <p>A paragraph for the main content.</p>
  <p>And another one.</p>

  <p slot="footer">Here's some contact info</p>
</base-layout>
Vue.component("baseLayout",{
			template:`
				<div class="container">
					<slot name="header"></slot>
					<slot></slot>
					<slot name="footer"></slot>
				</div>
			`
		})
        

ps:全局组件定义必须在new Vue()之前,否则控制台报错: Unknown custom element

编译作用域

父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译。

<todo-list :todos="todos">
    <template slot-scope="{todo}">
        {{todo}}
    </template>
</todo-list>
Vue.component("todo-list",{
    props:['todos'],
    template:`
        <ul>
            <li v-for="todo in todos">
                <slot :todo="todo">{{todo.name}}</slot>
            </li>
        </ul>
    `
});

slot-scope能获得子组件的数据,template能替换子组件slot中内容

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值