一、使用Slot,来提升组件的扩展性,比如
<template>
<button>
{{text}}
<slot></slot>
</button>
</template>
这样在使用组件的时候就非常灵活啦,既可以直接在属性上直接设置按钮的文本也可以直接像使用正常的DOM元素一样使用,如下代码
<ui-button types="block strong large" text="我是按钮"></ui-button>
或者
<ui-button types="block strong large">我是按钮</ui-button>
同样的如果把其他的组件来替换组件中的Slot,就可以实现组件间的嵌套,比如我们在开发Dialog组件时,就要格外关注它的扩展性。
首先,确定Dialog组件的结构,将用于嵌套的插槽预留出来,那么Dialog组件的代码组织就可以如下面写法
<template>
<div class="ui-dialog">
<div class="ui-dialog-hd" v-if="hasTitle">
<p class="dialog-title">{{title}}</p>
<slot name="dialog-header"></slot>
</div>
<div class="ui-dialog-bd">
<slot name="dialog-body"></slot>
</div>
<div class="ui-dialog-ft" v-if="hasFooter">
<slot name="dialog-footer"></slot>
</div>
</div>
</template>
上面的代码使用Vue的具名Slot特性,我们在使用的时候可以指定组件插到那个指定插槽,用法如下
<template>
<div id="app">
<ui-dialog :hasTitle="true" :hasFooter="true" title="Slot demo title">
<div class="bd-main" slot="dialog-body">
<h3>Dialog body</h3>
<p>Dialog content line1</p>
<p>Dialog content line2</p>
</div>
<div class="btn-wrapper" slot="dialog-footer">
<ui-button types="block strong large">我是按钮</ui-button>
</div>
</ui-dialog>
</div>
</template>
这样就可以随意在Dialog的框下面随意扩展使用,其他的组件嵌套以此类推。
二、组件内进行事件上报
组件内部不要试图去处理事件的业务逻辑部分,如果涉及到可自身控制的表现可以在事件内部自己去跟踪表现的变化,同时切记把事件进行上报,使用自定义事件发射、接收器的形式,代码上使用emit来上报事件。
以按钮组件为例
<template>
<button @click="clickHandler">
{{text}}<slot></slot>
</button>
</template>
<script>
export default{
name: 'ui-button',
methods:{
clickHandler(e){
//将click事件上报给父组件
this.$emit('click',e)
}
}
}
</script>
按钮本身的点击事件不涉及到自身表现的变化,因此只需要把click事件进行上报,由使用它的父组件(祖先组件)来处理它的示例逻辑。通过这种完全解耦的方式,让组件变得更为独立、更易用。