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中内容