?Hi~ 大家好,我是小鑫同学,一位长期从事前端开发的编程爱好者,我将使用更为实用的案例输出更多的编程知识,同时我信奉分享是成长的唯一捷径,在这里也希望我的每一篇文章都能成为你技术落地的参考~

?技术&代码分享

  • 我在 IT200 总结技术学习;
  • 我在 1024Code 在线编写代码;
  • 我在 掘金 分享技术文章;
  • 我在 Github 参与开源学习;

?推荐几个好用的工具

  • var-conv 适用于VSCode IDE的代码变量名称快速转换工具
  • generator-vite-plugin 快速生成Vite插件模板项目
  • generator-babel-plugin 快速生成Babel插件模板项目

进入正题

在各种场景的开发中Dialog组件的出现频率都是非常高的,Dialog组件作为一个容器组件受容器内业务代码复杂度的影响,代码行数、变量及函数的定义可能会很多,这样的组件就一定要考虑封装使用,以保证主流程代码的简洁。下面一起来看一下如何利用面向对象的思想来封装它吧~

技术选型

Vuejs3.x + Typescript + 是目前编写SFC组件的推荐方式,相比直接使用setup函数编码体验会更好,AntdV组件库的使用频率相比ElementUI要高,推荐新项目直接选用AntdV,完整代码可以在1024Code直接Fork或导出到本地。

代码分析

下面的代码来自AntdV组件库Model组件的示例,Model需要一个visible属性来控制是否显示和隐藏,由buttonclick事件来触发修改visible属性显示,并且可以通过ok事件的触发来表示对Model内业务逻辑的认可。

从这个示例来看代码当然是没有拆分组件的必要的,当但代表主流程业务的button和由modal包裹的业务流程变得多起来的时候,script里面的代码可读性将大大降低。

import { ref } from 'vue';const visible = ref(false);const showModal = () => {  visible.value = true;};const handleOk = (e: MouseEvent) => {  console.log(e);  visible.value = false;};  Open Modal      

Some contents...

Some contents...

Some contents...

普通的组件拆分

常规的组件拆分大家按习惯来做一定是考虑通过Props传递visible参数来控制子组件中Model组件的显示,但是你是没有办法直接将Propsvisible属性绑定到Model,因为在关闭弹窗是涉及到了修改变量,这样的做法在Vuejs中认为是危险的(父子组件单向数据流),所以必须要通过子组件重新定义变量来接收后使用;

另一个问题就是父组件在给子组件传visible参数时在父组件也有属性定义,这个属性在改为true后同样因单向数据流的限制是无法在Model关闭时动态变更为false,这样的Model就只能被打开一次,合理的解决范式就是通过emit在Model关闭时通知(回调)父组件,由父组件主动修改它定义的变量。

这样拆分组件不仅定义了多份控制显示/隐藏的变量,并且还需要在回调中专门处理,这给组件的开发和使用都造成了一定的麻烦,所以我不推荐这种拆分方式。

面向对象拆分组件

面向对象的第一大概念就是封装,所以只要涉及封装就完全可以用面向对象的思想来做,在案例中控制显示隐藏的visible属性和ok事件都是属于这个组件对象自己的,只能定义在子组件中。操作Model显示隐藏的方式不能通过Props传递,同样需要由组件对象自己提供,在使用了后,组件默认为关闭状态,需要使用defineExpose函数将需要暴露的函数暴露给父组件使用。前面提到的emit在这里还是比不可少了,但是仅仅是作为将业务处理的结果传递给父组件。

import { ref, defineExpose, defineEmits } from 'vue'const visible = ref(false);const open = () => visible.value = true;const close = () => visible.value = false;defineExpose({  open,})const emit = defineEmits()const handleOk = (_) => {  close();  emit('complete', 200);};      

Some contents...

Some contents...

Some contents...

面向对象使用组件

在面向对象封装时并不需要过多的考虑显示隐藏状态变化的传递,属于组件本身的属性、函数有组件自己控制包括是否对外暴露等,那么在使用的时候也是非常简洁的。在父组件中只关注Model什么时候需要打开和关闭后回调的数据处理即可。

import { ref } from 'vue';import BusinessDialog from './components/BusinessDialog.vue';const businessDialogRef = ref<InstanceType>();const showModal = () => {  businessDialogRef.value?.open();}const onComplete = (e: any) => {  console.log(e);}  Open Modal  

总结

文中介绍的关于DialogComponent组件的封装思想是我所推荐的,因为它不仅开发子组件是不需要过多外部的干扰,在使用子组件是也不需要过多的考虑,这也是封装的意义所在,在其中使用到了defineExpose()defineEmits(),对于很少使用方式的小伙伴也是不熟悉的,可以通过Vuejs文档学习,最后在父组件定义子组件的ref时使用的InstanceType属于Typescript中的类型编程,感兴趣的也可以了解一下。好了,今天就说这么多,下次见~

PS:完整代码见1024Code;


如果看完觉得有收获,欢迎点赞、评论、分享支持一下。你的支持和肯定,是我坚持写作的动力~

本文来自博客园,作者:FE小鑫同学,转载请注明原文链接:https://www.cnblogs.com/it200/p/17190915.html