gpt4 book ai didi

Element-ui源码解析(二):最简单的组件Button

转载 作者:我是一只小鸟 更新时间:2023-07-25 22:31:28 25 4
gpt4 key购买 nike

好家伙,为了有足够的能力去开发组件,先研究一下别人的组件 。

开始 抄袭 模仿我们的行业标杆element-ui 。

  。

找到Button组件的源码 。

 只有三个文件,看上去非常易读,开搞 。

  。

 其中最重要的部分,自然是button.vue 。

                        
                           <template> <  button class  =  "   el-button   "   @click  =  "   handleClick   "   :disabled  =  "   buttonDisabled || loading   "   :autofocus  =  "   autofocus   "   :type  =  "   nativeType   "   :class  =  "   [  type ?  '   el-button--   '  + type :  ''   , buttonSize  ?  '   el-button--   '  + buttonSize :  ''   , {   '   is-disabled   '   : buttonDisabled,   '   is-loading   '   : loading,   '   is-plain   '   : plain,   '   is-round   '   : round,   '   is-circle   '   : circle } ]   "  > <i class=  "   el-icon-loading   "  v-  if  =  "   loading   "  ></i> <i :class=  "   icon   "  v-  if  =  "   icon && !loading   "  ></i> <span v-  if  =  "   $slots.default   "  ><slot></slot></span> </button> </template> <script>  export default { name:   '   ElButton   '   , inject: { elForm: { default:   ''   }, elFormItem: { default:   ''   } }, props: { type: { type: String, default:   '   default   '   }, size: String, icon: { type: String, default:   ''   },   //   图标样式   nativeType: { type: String, default:   '   button   '   }, loading: Boolean, disabled: Boolean, plain: Boolean, autofocus: Boolean, round: Boolean, circle: Boolean }, computed: { _elFormItemSize() { return (this.elFormItem  ||  {}).elFormItemSize; }, buttonSize() { return this.size  || this._elFormItemSize || (this.$ELEMENT ||  {}).size; }, buttonDisabled() { return this.$options.propsData.hasOwnProperty(   '   disabled   '  ) ? this.disabled : (this.elForm ||  {}).disabled; } }, methods: { handleClick(evt) { this.$emit(   '   click   '   , evt); } } };  </script> 
                        
                      

  。

既然是.vue那么我们把它分成DOM,属性,方法三部分来分析 。

我们首先看属性,看完属性,你自然知道DOM里面的值绑的是什么鬼了 。

  。

1.属性

                        
                           name:  '   ElButton   '   ,   //   inject用于接收父组件的传值,然而我并找到传这个值的父组件   inject: { elForm: { default:   ''   }, elFormItem: { default:   ''   } }, props: {   //   按钮大样式   type: { type: String, default:   '   default   '   },   //   大小选择   size: String,   //   图标选择   icon: { type: String, default:   ''   },   //   按钮小样式   nativeType: { type: String, default:   '   button   '   }, loading: Boolean,   //   是否加载中状态  disabled: Boolean,  //   是否禁用状态  plain: Boolean,  //   是否朴素按钮  autofocus: Boolean,  //   是否默认聚焦  round: Boolean,  //   是否圆角按钮  circle: Boolean  //   是否圆形   }, computed: {   //   父组件的值,   _elFormItemSize() { return (this.elFormItem  ||  {}).elFormItemSize; },   //   按钮尺寸属性   //   其中,在越左边的属性优先级越高,size的属性优先级最高   buttonSize() { return this.size  || this._elFormItemSize || (this.$ELEMENT ||  {}).size; },   //   按钮是否禁用   buttonDisabled() { return this.$options.propsData.hasOwnProperty(   '   disabled   '  ) ? this.disabled : (this.elForm ||  {}).disabled;   //   this.$options.propsData 是一个包含了组件实例的 props 数据的对象。   //   hasOwnProperty('disabled') 是 JavaScript 中的一个方法,用于判断对象是否具有某个属性。   } },  
                        
                      

总体看上去没有什么难理解的点,但还是有几个地方要注意 。

  。

问题一:在计算属性 computed中 。

  。

                        
                            //   父组件的值,   _elFormItemSize() { return (this.elFormItem  ||  {}).elFormItemSize; },  
                        
                      

为什么是 。

                        
                            (this.elFormItem || {}).elFormItemSize;  
                        
                      

而不直接写成 。

                        
                           this.elFormItem.elFormItemSize 
                        
                      

  。

这段代码使用 ` (this.elFormItem || {}).elFormItemSize`的形式来获取 ` elFormItemSize`属性的值.

` (this.elFormItem || {})`的作用是先判断 this.elFormItem 是否存在, 。

如果存在则返回 `this.elFormItem` 的值,否则返回一个空对象 `{}`.

在这种情况下,如果 `this.elFormItem` 不存在,那么后续对 `elFormItemSize` 的访问将会返回 `undefined`.

这种写法是为了避免在 `this.elFormItem` 为 `null` 或 `undefined` 的情况下访问 `elFormItemSize` 属性时出现报错.

通过使用短路运算符 `||` 和空对象 `{}`,可以确保代码的健壮性, 。

即,使 `this.elFormItem` 不存在也不会导致程序崩溃,而是安全地访问属性并返回结果.

  。

  。

第二部分:DOM

                        
                           < 
                           template> <button class="el-button" @click="handleClick" :disabled="buttonDisabled || loading" :autofocus="autofocus" :type="nativeType" :class="[ type ? 'el-button--' + type : '', buttonSize ? 'el-button--' + buttonSize : '', { 'is-disabled': buttonDisabled, 'is-loading': loading, 'is-plain': plain, 'is-round': round, 'is-circle': circle } ]" > <i class="el-icon-loading" v-if="loading"></i> <i :class="icon" v-if="icon && !loading"></i> <span v-if="$slots.default"><slot></slot></span> </button> </template> 
                        
                      

注释版本

                        
                           <!-- <button class=  "   el-button   "   //   样式  @click=  "   handleClick   "   //   点击事件  :disabled=  "   buttonDisabled || loading   "   //   disabled原生属性   //   此布尔属性表示用户不能与 button 交互。  :autofocus=  "   autofocus   "   //   autofocus原生属性,一个布尔属性,   //   用于指定当页面加载时按钮必须有输入焦点,除非用户重写,例如通过不同控件键入。  :type=  "   nativeType   "   //   type原生属性,type 属性定义了按钮的类型, 指定了按钮的行为和样式  
                        
                      
      :class="[
                        
                           type ?  '   el-button--   '  + type :  ''  ,  //   那几个按钮样式,红的蓝的绿的  buttonSize ?  '   el-button--   '  + buttonSize :  ''  ,  //   按钮大小   {   '   is-disabled   '  : buttonDisabled,  //   是否禁用状态   '   is-loading   '  : loading,  //   是否加载中状态   '   is-plain   '  : plain,  //   是否朴素按钮   '   is-round   '  : round,  //   是否圆角按钮   '   is-circle   '  : circle  //   是否圆形   } ]   "   >  <i class=  "   el-icon-loading   "  v-  if  =  "   loading   "  ></i>  //   是否显示加载中状态  <i :class=  "   icon   "  v-  if  =  "   icon && !loading   "  ></i>  //   显示对应图标  <span v-  if  =  "   $slots.default   "  > <slot></slot> </span>  //   插槽用于渲染名字  </button> --> 
                        
                      

  。

2.1.问题一:"class"与:"class"的优先级?

答:当同一个元素同时存在  class  和  :class  属性时, class  属性中的类名会与  :class  动态计算的类名进行合并, 。

但是  :class  的优先级更高 。 :class  中定义的类名会覆盖  class  中的类名 .

  。

2.2.问题二:":class"中的样式如何渲染

1.type ? 'el-button--' + type : '  ':这个表达式根据type变量的值,生成一个按钮类型的class。
如果type有值(不为false、null、undefined、0或空字符串),则 生成类似于el-button--type的class ,否则生成空字符串。
   
2.buttonSize ? 'el-button--' + buttonSize : '  ':这个表达式根据buttonSize变量的值,生成一个按钮大小的class。
如果buttonSize有值,则生成类似于el-button--buttonSize的class,否则生成空字符串。
   
3.对象字面量{ }用于根据变量的真假值来动态添加/移除某些class。
根据以下变量的值,如果为真,则添加相应的class:'is-disabled'(按钮禁用状态),
'is-loading'(按钮加载中状态),'is-plain'(按钮朴素风格),'is-round'(按钮圆角风格),
'is-circle'(按钮圆形风格)。
 
 
2.3.关于原生属性autofocus的作用?

autofocus 属性是HTML中用于设置按钮自动聚焦的属性.

当页面加载完成后, 被设置为 autofocus 的按钮将自动获取焦点,无需用户操作 .

这可以提供用户友好的交互,特别是当页面上有多个按钮时,自动聚焦可以使页面更易于导航.

使用 autofocus 属性的语法如下所示:

                            
                               <button autofocus>Submit</button> 
                            
                          

在这个例子中,当页面加载完成后,提交按钮将自动获得焦点,用户可以直接通过按下回车键来提交表单(如果有,登陆注册).

  。

  。

第三部分:JS方法

                        
                            methods: { handleClick(evt) {   this  .$emit('click'  , evt); }   //   触发'click'方法,并将evt作为参数传入  } 
                        
                      

触发自定义方法click,将evt作为参数传入 。

  。

最后此篇关于Element-ui源码解析(二):最简单的组件Button的文章就讲到这里了,如果你想了解更多关于Element-ui源码解析(二):最简单的组件Button的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com