网站建设 软文发布,沈阳专业制作网站公司哪家好,宝山网页设计制作,网站建设目标 优帮云1、需求说明 需求背景#xff1a;日常开发中#xff0c;我们经常会使用一些UI组件库诸如and design vue、element plus等辅助开发#xff0c;提升效率。有时我们需要进行个性化封装#xff0c;以满足在项目中大量使用的需求。 错误示范#xff1a;基于a-modal封装一个自定…1、需求说明 需求背景日常开发中我们经常会使用一些UI组件库诸如and design vue、element plus等辅助开发提升效率。有时我们需要进行个性化封装以满足在项目中大量使用的需求。 错误示范基于a-modal封装一个自定义Modal组件修改modal样式按钮样式、每次关闭后销毁、渲染到指定元素上等等后续项目的弹窗全部基于该自定义组件。
templatediv refmyModal classcustom-modal/diva-modalv-model:visiblevisiblecentereddestroyOnClose:getContainer() $refs.myModalokhandleOkcancelhandleCancel:style{ width: 560px, ...style }:cancelTextcancelText:okTextokText!-- 以上皆为该组件的默认属性 --slot/slot/a-modal
/templatescript setup
const props defineProps({title: {type: String,default: ,},style: {type: Object,default: () ({}),},cancelText: {type: String,default: 取消,},okText: {type: String,default: 确定,},
});
const emits defineEmits([handleOk, handleCancel]);
const visible ref(false);const handleOk () {emits(handleOk);
};
const handleCancel () {emits(handleCancel);
};
defineExpose({ visible });
/scriptstyle langless scoped
.custom-modal {:deep(.ant-modal) {//省略几百行样式代码}
}
/style代码封装完成,于是乎我们便能在项目中应用带有项目风格的弹窗
CustomModal refxxxModal titlexxx okonXxx cancelonXxx content/CustomModal2、$attrs 问题来了一切看起来都挺正常。直到有一天同事说我想要去掉右上角的关闭按钮,能改成自定义的吗简单直接加! !-- 省略不相关代码 --
a-modal :closableclosable/a-modal
script setup
const props defineProps({//...closable:{type: Boolean,default: false}
});
/script另一位同事说我不想让它是居中的能改成自定义的吗还有一位同事说…思考这样的情况多了就有点难顶。每次一有新的需求我就得改这个组件导致这个组件代码越来越冗余。那么是否有一种方式能够将传进来的属性自动绑定给a-modal呢有那就是attrs
注意
1.vue提供了$attrs这么一个属性用于接收父组件传递下来的属性$attrs不包括已经写入props的值
2.如果父组件传递了styleclass那么这这些值不仅会存在于$attrs还会默认绑定至根元素上。这一点需要注意modalTest :footernull :centeredfalse :zIndex999 /
//此时的$attrs
{ footer: null, centered: false, zIndex: 999 }有了这个组件实例结合v-bind我们就可以这么写 a-modalv-model:visiblevisiblecentereddestroyOnClose:getContainer() $refs.myModal:style{ width: 560px, ...style }v-bind$attrs!-- 略 --/a-modal这样一来我们就可以使用a-modal提供的任意属性和方法了
3、$slots 问题来了插槽怎么办例如a-modal就提供了许多插槽是不是要用哪个就先在自定义组件上写好呢 错误示例:
a-modal!-- default --slot/slot!-- title --template #title
slot nametitle{{ title }}/slot/template!-- other --
/a-modal弊端就像之前的如果该原生提供了许多插槽当有需要时岂不是频繁去修改自定义组件添加相应的插槽其实利用$slots可以解决这个问题 官网的这段话简明扼要的说出的插槽的原理我们所传递的插槽最终都是变成
{slotNamefn(...args) //fn返回一个虚拟DOMdefautl: fn(...args) //默认插槽
}也就是我们传什么插槽进来 s l o t s 就有什么值那么我们可以遍历 slots就有什么值那么我们可以遍历 slots就有什么值那么我们可以遍历slots中的值有什么插槽我们便动态绑定什么插槽
a-modaltemplate v-for(_val, name) in $slots #[name]optionsslot :namename v-bindoptions || {} /slot/template
/a-modal#[name]“options”我们可以拿到原生a-modal在name这个插槽中传递来的一些状态options并绑定在上。详情请查看官网作用域插槽[1]。 这样一来我们原生a-modal怎么使用插槽自定义组件就怎么使用插槽
CustomModaltemplate #title{arg1, arg2}content/template
/CustomModal至此封装的代码如下
templatediv refmyModal classcustom-modal/diva-modalv-model:visiblevisiblecentered:getContainer() $refs.myModal:style{ width: 560px}destroyOnClosev-bind$attrstemplate v-for(_val, name) in $slots #[name]opsslot :namename v-bindops || {} /slot/template/a-modal
/templatescript setup
const visible ref(false);
defineExpose({ visible });
/scriptstyle langless scoped
.custom-modal {//style
}
/style还有许多优化的空间例如当前父组件显隐该Modal需使用ref的方式访问visible。在vue3中也可以参考官网的做法这样子写
templatediv refmyModal classcustom-modal/diva-modal:visiblevisible//....v-bind$attrs!-- ... --/a-modal
/templatescript setup
defineProps([visible])
const emit defineEmits(); // 不用写update:visiblevue会自动加上
watch(() props.visible,(newVal) emit(update:visible, newVal);
);
/script那么使用这个控制这个组件的显示隐藏就方便许多了
CustomModal v-model:visiblevisible/CustomModal本文中的封装方式是基于vue3来进行实现不局限在什么UI组件身上。如果使用的是vue2情况稍有不同请自行了解。