• element ui源码解析 -- button篇


    要看源码就得从最简单的开始,button够简单的了,就从他开始吧。

    安装依赖后源码目录在:node_modules/element-ui/packages中,可以看到这里的文件夹命名是不是很熟悉,就是我们平时写的组件名,打开任何一个文件夹,都有一个src文件夹和一个index.js,src文件夹放组件,index.js用于注册组件

    下面来看具体的button源码如何写的:

    分析从三个方面着手:DOM结构,数据属性,事件

    DOM结构:

    按钮的DOM结构很简单,要显示成什么样子就由css样式及一些自带的属性决定了,这些就交给数据属性来控制

    <button></button>
    

      

    数据属性:

    按钮的样式,大小,显示内容,类型等都需要通过数据属性来控制,这些数据属性分两块:

    a、直接引用props

    b、引用computed的属性

    直接引用props的数据大家都能理解,为什么还用到computed呢?

    这里就涉及到provider/inject,

    provider/inject:简单的来说就是在父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量。注意官方文档有一句话“向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效”,这样看来就明显了,父组件提供的属性只能在直接子组件中获取到,孙组件就获取不到,provide提供的属性就解决了这个问题。

    为什么用到computed?答案就很明显了,防止全局设置/父组件的属性,孙组件获取不到

    Vue.use(Element, {
      size: Cookies.get('size') || 'medium' // set element-ui default size
    })
    

      

    有了provider/inject,这里配置的size才能全局起作用。

    事件:

    这里涉及到父子组件通信,子组件向父组件发消息可以用emit实现,父组件监听即可,一般情况下父组件监听的事件名都是自定义的,这里特殊了点,父组件直接监听了“click”事件,谁让button通常就一个点击事件呢

    index.js:

    js的作用很简单,注册组件并导出

    最后:

    源码DOM结构上有这样一句:

    <span v-if="$slots.default"><slot></slot></span>
    

     

    我们知道插槽有具名插槽和不具名插槽,“$slots.default”指代的就是不具名插槽。为什么要这么写,而不是:

    <span><slot></slot></span>
    

      

    这里其实是一个很细心的点,如果<el-button></el-button>不写内容,将会少一个span节点,渲染后的DOM是这样的

    <button data-v-06af20c4="" type="button" class="el-button el-button--default el-button--medium"></button>
    

      

    如果去掉v-if="$slots.default",渲染后将是这样的

    <button data-v-06af20c4="" type="button" class="el-button el-button--default el-button--medium"><span></span></button>
    

      

     ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    除了学知识,我们还可以从源码中学到一点规范:

    :class="[
          type ? 'el-button--' + type : '',
          buttonSize ? 'el-button--' + buttonSize : '',
          {
            'is-disabled': buttonDisabled,
            'is-loading': loading,
            'is-plain': plain,
            'is-round': round,
            'is-circle': circle
          }
    

      

    绑定的class做了归类,boolean类型的归为了一类,放到对象中,我们是不是也可以这样写,让代码更整齐呢

  • 相关阅读:
    websocket协议图
    go深浅拷贝
    nginx不匹配location前缀
    nginx localtion 的alias是一个目录别名的定义,root则是最上层目录的定义
    启动了多个redis,怎么知道哪个redisserver使用的是哪个配置文件?
    go打印地址
    Linux之pureftpd安装和使用
    Xtrabackup异机远程备份
    产品新版本发布前要做那些事呢
    2014年新的一年,新的起点。。。
  • 原文地址:https://www.cnblogs.com/diantao/p/10838676.html
Copyright © 2020-2023  润新知