当前位置: 首页 > Web前端 > vue.js

从Element3学Vue3.0-el-button

时间:2023-03-31 22:52:00 vue.js

阅读本文之前,我假设你已经掌握了Vue3.0的基本使用。文章主要分析了组件开发过程中的思路和一些Api的解释。希望本文能帮助大家更好的理解Element3和Vue3.0的使用以及组件的开发。模板废话就不细说了,先从上面提到的Element3Git地址拉取最新的源码,然后在package文件夹中的button文件夹下找到Button.vue,这个组件就是介绍第一个组件.我不会详细介绍tempalte。大致内容如下:不用多说了,上面结构中的loading在这里比较流行。这个地方优先加载,其次是加载icon图标,Button组件中也使用了$slots.default。该值指向插入到当前组件中的默认插槽,通常称为匿名插槽。这里使用了一个非常巧妙的技巧,即如果匿名组件存在,则使用插槽,而不是直接将组件挂载到插槽中。这个很nice~propsbutton是动态绑定calss、type、disabled的。我们以后再说。先标记一下,先看组件的入参(即:props):exportdefault{props:{//控制按钮的大小:{type:String,validator(val){if(val==='')returntruereturn['medium','small','mini'].indexOf(val)!==-1}},//控制按钮类型type:{type:String,validator(val){return(['primary','success','warning','danger','info','text'].indexOf(val)!==-1)}},//原生类型nativeType:{type:String,default:'button'},//是否为普通按钮plain:Boolean,//是否为圆角按钮round:Boolean,//是否为圆形circle:Boolean,//是否加载loading:Boolean,//是否禁用disabled:Boolean,//图标类名icon:String}};从上面的源码我们可以看出size和type参数使用了一个自定义的校验器(validator),如果你没有仔细阅读过Vue文档,你可能对validator有点陌生。Validator可以在方法中更准确的指定参数的值,比如size,只能传入medium、small、mini。验证器方法返回一个布尔值。当没有传入指定的值时,会抛出错误invalidprop。也就是说validator会根据返回值true通过身份验证,并返回error表示验证失败。细心的朋友可能已经发现,属性native-typenative属性也被挂载了,但是这个值并没有使用验证器来验证值。也许Element3开发人员可以促进未来的扩展。如果原声中的native-type可以通过添加其他依赖值的组件库项目直接使用,不需要改变组件库部分,也不希望组件库影响一些native属性。笔者也看了文档。在Element3中Button的文档中,提供了autofocus属性,但是组件中并没有接收到这个属性。这个时候我们再来看一下HTML部分。在模板中,直接就是button标签,所以我们在中已经挂载了Autofocus。逻辑处理介绍完参数部分,我们继续往下看setup。经过Vue3.0的改进,setup已经承载了页面中的大部分逻辑,el-button也是自然而然的。从'../../src/use/globalConfig'导入{useGlobalOptions};import{toRefs,inject,computed}from'vue'exportdefault{setup(props){const{size,disabled}=toRefs(props)constbuttonSize=useButtonSize(size)constbuttonDisabled=useButtonDisabled(disabled)constclasses=useClasses({props,size:buttonSize,disabled:buttonDisabled})return{buttonDisabled,classes}}}由于setup中没有this,所以第一个A参数是props传入的parameter属性参数,但是获取到的对象是普通的无法完成双向绑定的对象,通过toRefs转换为绑定对象。buttonSize在setup中统一处理类,下面我们来看这部分的内容。方法中首先处理了buttonSize,具体代码如下。constuseButtonSize=(size)=>{//获取当前组件实例constglobalConfig=useGlobalOptions()returncomputed(()=>{constelFormItem=inject('elFormItem',{})returnsize?.value||elFormItem.elFormItemSize||globalConfig.size})}src/use/globalConfigexportfunctionuseGlobalOptions(){//获取当前组件实例constinstance=getCurrentInstance()if(!instance){console.ware('useGlobalOptionsmustbecallinsetup函数')返回}返回instance.appContext.config.globalProperties.$ELEMENT||{}}在useButtonSize方法中,通过public方法获取当前组件的实例。如果当前组件的实例存在,则通过全局属性获取当前组件全局信息(组件全局信息实际上是初始化时手动配置的信息,命名为$ELEMENT),如果没有获取到全局信息,则返回一个空对象默认。然后通过inject接收父elFormItem传过来的数据,传入一个空对象作为默认值。以上操作完成后,在useButtonSize方法中通过计算属性得到size属性的值,其优先级为props>elFormItem>globalConfig,最后返回计算结果。useButtonDisabled经过以上处理后,处理按钮是否可用。具体代码如下:constuseButtonDisabled=(disabled)=>{returncomputed(()=>{constelForm=inject('elForm',{});returndisabled?.value||elForm.disabled;});};其实这里的处理逻辑和按钮大小的处理类似。代码这里就不赘述了,这里也返回了获取到的值。这里接收的不再是elFormItem的值,而是elForm的值。从这里可以得出结论,在elForm中传递Element3的按钮会禁用整个表单。注:关于inject接收到的值,这里不再赘述。在分析其成分时,会加以说明。useClasses获取所有参数后,通过useClasses方法统一处理类名:constuseClasses=({props,size,disabled})=>{returncomputed(()=>{return[size.value?`el-button--${size.value}`:'',props.type?`el-button--${props.type}`:'',{'is-plain':props.plain,'is-round':props.round,'is-circle':props.circle,'is-loading':props.loading,'is-disabled':disabled.value}]})}这里关于类动态渲染,计算属性用于代替一对一绑定。这样做的好处是可以统一保持其类的风格,还有一点要说的是,在渲染一个类的时候,使用了数组嵌套对象的形式。可能作者稍微好点,我没用过这种方法动态渲染一个类。从代码中可以明显看出,useClasses方法只是简单的计算数据对。所有相关类名统一处理。别戳针~综上所述,上面的代码就是整个el-button组件。虽然是一个很简单的组件,但是你可以在里面学到一些东西,比如Vue3.0的Provide/Inject。整体代码思路清晰,代码结构简洁,值得我们借鉴。没有时间安静,但有人为你背负重担。感谢为Element3默默贡献的程序大师们。如果您有兴趣,请单击下面的链接并为其加注星标。Element3Git地址Element3官方文档