Professional Documents
Culture Documents
js 组件的三个 API:
prop、event、slot
如果您已经对 Vue.js 组件的基础⽤法了如指掌,可以跳过本⼩
节,不过当做复习稍读⼀下也⽆妨。
组件的构成
⼀个再复杂的组件,都是由三部分组成的:prop、event、slot,它
们构成了 Vue.js 组件的 API。如果你开发的是⼀个通⽤组件,那⼀
定要事先设计好这三部分,因为组件⼀旦发布,后⾯再修改 API 就
很困难了,使⽤者都是希望不断新增功能,修复 bug,⽽不是经常
变更接⼝。如果你阅读别⼈写的组件,也可以从这三个部分展开,它
们可以帮助你快速了解⼀个组件的所有功能。
属性 prop
prop 定义了这个组件有哪些可配置的属性,组件的核⼼功能也都是
它来确定的。写通⽤组件时,props 最好⽤对象的写法,这样可以
针对每个属性设置类型、默认值或⾃定义校验属性的值,这点在组件
开发中很重要,然⽽很多⼈却忽视,直接使⽤ props 的数组⽤法,
这样的组件往往是不严谨的。⽐如我们封装⼀个按钮组件 <i-
button>:
<template>
<button :class="'i-button-size' + size"
:disabled="disabled"></button>
</template>
<script>
// 判断参数是否是其中之⼀
function oneOf (value, validList) {
for (let i = 0; i < validList.length; i++) {
if (value === validList[i]) {
return true;
}
}
return false;
}
export default {
props: {
size: {
validator (value) {
return oneOf(value, ['small', 'large',
'default']);
},
default: 'default'
},
disabled: {
type: Boolean,
default: false
}
}
}
</script>
使⽤组件:
<i-button size="large"></i-button>
<i-button disabled></i-button>
要注意的是,组件⾥定义的 props,都是单向数据流,也就是只能
通过⽗级修改,组件⾃⼰不能修改 props 的值,只能修改定义在
data ⾥的数据,⾮要修改,也是通过后⾯介绍的⾃定义事件通知⽗
级,由⽗级来修改。
插槽 slot
<i-button>按钮 1</i-button>
<i-button>
<strong>按钮 2</strong>
</i-button>
当需要多个插槽时,会⽤到具名 slot,⽐如上⾯的组件我们再增加
⼀个 slot,⽤于设置另⼀个图标组件:
<template>
<button :class="'i-button-size' + size"
:disabled="disabled">
<slot name="icon"></slot>
<slot></slot>
</button>
</template>
<i-button>
<i-icon slot="icon" type="checkmark"></i-icon>
按钮 1
</i-button>
<slot>提交</slot>
⾃定义事件 event
<template>
<button @click="handleClick">
<slot></slot>
</button>
</template>
<script>
export default {
methods: {
handleClick (event) {
this.$emit('on-click', event);
}
}
}
</script>
<i-button @on-click="handleClick"></i-button>
组件的通信
⼀般来说,组件可以有以下⼏种关系:
ref:给元素或组件注册引⽤信息;
$parent / $children:访问⽗ / ⼦实例。
这两种都是直接得到组件实例,使⽤后可以直接调⽤组件的⽅法或访
问数据,⽐如下⾯的示例中,⽤ ref 来访问组件(部分代码省略):
// component-a
export default {
data () {
return {
title: 'Vue.js'
}
},
methods: {
sayHello () {
window.alert('Hello');
}
}
}
<template>
<component-a ref="comA"></component-a>
</template>
<script>
export default {
mounted () {
const comA = this.$refs.comA;
console.log(comA.title); // Vue.js
comA.sayHello(); // 弹窗
}
}
</script>
// parent.vue
<component-a></component-a>
<component-b></component-b>
<component-b></component-b>
结语
本⼩节带您复习了 Vue.js 组件的核⼼知识点,虽然这并没有完全覆
盖 Vue.js 的 API,但对于组件开发来说已经⾜够了,后续章节也会
陆续扩展更多的⽤法。
基于 Vue.js 开发独⽴组件,并不是新奇的挑战,坦率地讲,它本质
上还是 JavaScript。掌握了 Vue.js 组件的这三个 API 后,剩下的便
是程序的设计。在组件开发中,最难的环节应当是解耦组件的交互逻
辑,尽量把复杂的逻辑分发到不同的⼦组件中,然后彼此建⽴联系,
在这其中,计算属性(computed)和混合(mixins)是两个重要
的技术点,合理利⽤,就能发挥出 Vue.js 语⾔的最⼤特点:把状态
(数据)的维护交给 Vue.js 处理,我们只专注在交互上。
当您最终读完本⼩册时,应该会总结出和笔者⼀样的感悟:Vue.js
组件开发,玩到最后还是在拼 JavaScript 功底。对于每⼀位使⽤
Vue.js 的开发者来说,阅读完本⼩册都可以尝试开发和维护⼀套属
于⾃⼰的组件库,并乐在其中,⽽且你会越发觉得,⼀个组件或⼀套
组件库,就是融合了前端精髓的产出。
扩展阅读
Vue 组件通信之 Bus
(https://juejin.im/post/5a4353766fb9a044fb080927)
Vuex 通俗版教程
(https://juejin.im/entry/58cb4c36b123db00532076a2)