ElementUI是一款非常流行的vue插件库,整合了开发中大多数的组件。

最近正好在学习vue,就尝试简单模拟一下el-button的实现。

最近正好在学习vue,就尝试简单模拟一下el-button的实现。

  1. 引入vue核心js
  <script src="vue.js"></script>

2.用Vue.component语法设置全局插件

Vue.component('elButton', {

    name: 'elButton',

    props: {

        type: {

            type: String,

            default: "default"

        }

    },

    data() {

        return {}

    },

    template: `

< button :class="'el-button el-button--' + type" @click="triggerClick">

  

  <slot></slot>

< /button>

  `,

    mounted() {


    },

    methods: {

        triggerClick(){

            this.$emit('click', "模拟参数");

        }

    },

});

3.调用过程

<el-button type="primary" @click="add">新增</el-button>

<el-button type="warning">修改</el-button>

<el-button type="danger">删除</el-button>

4.如何控制按钮颜色的?

核心就在于这一段代码:

 <button :class="'el-button el-button--' + type" @click="triggerClick">

type是外部组件传进来的参数,这边就直接字符串拼接了。然后会对应到具体的class

 

/*el-button组件样式*/
.el-button {
    display: inline-block;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    background: #fff;
    border: 1px solid #dcdfe6;
    border-color: #dcdfe6;
    color: #606266;
    -webkit-appearance: none;
    text-align: center;
    box-sizing: border-box;
    outline: none;
    margin: 0;
    transition: .1s;
    font-weight: 500;
    -moz-user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;
    padding: 12px 20px;
    font-size: 14px;
    border-radius: 4px;
}

.el-button--default {

}

.el-button--primary {
    color: #fff;
    background-color: #409eff;
    border-color: #409eff;
}

.el-button--success {
    color: #fff;
    background-color: #67c23a;
    border-color: #67c23a;
}

.el-button--warning {
    color: #fff;
    background-color: #e6a23c;
    border-color: #e6a23c;
}

.el-button--danger {
    color: #fff;
    background-color: #f56c6c;
    border-color: #f56c6c;
}

如果不传type,就是default。

5.如何实现点击事件?

外部组件直接放心地添加@click事件,然后el-button组件内部用$emit去触发即可。

6.$emit的原理是啥?

这是vue内部去做的,不过也可以手动替换Vue原型链的$emit方法:

    Vue.prototype.$emit = function (event) {


        let _events = this._events;


        let cbs = _events[event];

        if (cbs) {

            cbs[0].apply(app, [arguments].splice(1));

        }

    }

这是一个简单的实现,实际实现会更加复杂。

this就指向当前的Vue实例,也是页面中唯一的那个vue实例,_events是所有设置的方法和事件,比如你写在methods里面的add方法。

思路还是很直白的,就是遍历所有事件,看看当前触发的是哪一个事件,找到了就直接用apply去调用。为啥用apply而不用call?源码就这么写的,用call其实也一样,只不过后面的参数不能用数组了,要用变长参数。好像是这样的,具体不记得了。

得到的event竟然是一个数组,搞不懂为啥vue要这么设计。

 

posted on 2022-04-30 16:43  剽悍一小兔  阅读(33)  评论(0编辑  收藏  举报  来源