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要这么设计。