通常项目开发时,UI出图的样式并不是与第三方UI组件相同的,那么就需要对常用UI组件进行二次封装。在封装的时候第三方组件提供了多个属性、事件、插槽,虽然可以一个一个依次声明赋值,但是这样也太过于繁琐。我们可以通过使用vue2中$attrs、$listeners、$slots分别来解决以上问题。
$attrs
是一个对象,包含了父作用域中传递给组件的非 prop 属性。它可以用来在组件中将这些非 prop 属性传递给内部的子组件。当一个组件没有声明接收某个属性,但父组件传递了该属性时,该属性就会出现在 $attrs
对象中。
$listeners
是一个对象,包含了父作用域中传递给组件的所有事件监听器。它可以用来在组件中将这些事件监听器传递给内部的子组件,从而实现事件的透传。
$slots
是一个对象,包含了组件的插槽内容。插槽允许在组件的模板中插入额外的内容,这些内容可以是普通的 HTML 或其他组件。$slots
对象的属性名对应着插槽的名称,值则是插槽中的内容。
具体示例代码如下:
二次封装vant field组件
<template>
<div>
<van-field v-bind="$attrs" v-on="$listeners">
<!--循环遍历父组件传递的插槽 -->
<template v-for="(value,key) in $slots" #[key]="slotData">
<!-- 个别插槽可以插槽传值-->
<slot :name="key" v-bind="slotData || {}">
</slot>
</template>
</van-field>
</div>
</template>
<script>
export default {
name: "index",
}
</script>
<style scoped>
</style>
使用二次封装的field组件,使用跟vant文档一致的属性、事件、插槽
<template>
<div>
<m-field ref="mField" v-model="fieldValue" placeholder="请输入测试" @focus="onfocus()">
<template #label>
<span>地址</span>
</template>
<template #left-icon>
<span>x</span>
</template>
</m-field>
</div>
</template>
<script>
import MField from '../../../src/components/myCmp/MField/index'
export default {
name: "FormTest",
components:{
MField
},
mounted() {
},
data(){
return {
fieldValue:'',
}
},
methods:{
onfocus(){
console.log('触发聚焦')
}
}
}
</script>
<style scoped>
</style>