临近毕业,写了个简单我的博客,项目地址是点我访问项目地址(顺便求star),本篇是系列总结第一篇。接下来会一步一步模仿一个低配版的Element 的对话框
和弹框
组件。css
当使用vue-cli
初始化一个项目的时候,会发现src/components
文件夹下有一个HelloWorld.vue
文件,这即是
单文件组件的基本开发模式。vue
// 注册 Vue.component('my-component', { template: '<div>A custom component!</div>' }) // 建立根实例 new Vue({ el: '#example' })
接下来,开始写一个dialog
组件。ios
目标对话框组件的基本样式如图:git
根据目标样式,能够总结出:github
title
props来标示弹窗标题肯定
按钮时发射
出肯定
事件(即告诉父组件肯定
了)发射
出取消
事件那么,编码以下:vue-cli
<template> <div class="ta-dialog__wrapper"> <div class="ta-dialog"> <div class="ta-dialog__header"> <span>{{ title }}</span> <i class="ios-close-empty" @click="handleCancel()"></i> </div> <div class="ta-dialog__body"> <slot></slot> </div> <div class="ta-dialog__footer"> <button @click="handleCancel()">取消</button> <button @click="handleOk()">肯定</button> </div> </div> </div> </template> <script> export default { name: 'Dialog', props: { title: { type: String, default: '标题' }, }, methods: { handleCancel() { this.$emit('cancel') }, handleOk() { this.$emit('ok') }, }, } </script>
这样便完成了dialog
组件的开发,使用方法以下:promise
<ta-dialog title="弹窗标题" @ok="handleOk" @cancel="handleCancel"> <p>我是内容</p> </ta-dialog>
这时候发现一个问题,经过使用v-if
或者v-show
来控制弹窗的展示时,没有动画!!!,看上去很生硬。教练,我想加动画
,这时候就该transition
组件上场了。使用transition
组件结合css
能作出不少效果不错的动画。接下来加强dialog
组件动画,代码以下:app
<template> <transition name="slide-down"> <div class="ta-dialog__wrapper" v-if="isShow"> // 省略 </div> </transition> </template> <script> export default { data() { return { isShow: true } }, methods: { handleCancel() { this.isShow = false this.$emit('cancel') }, handleOk() { this.isShow = true this.$emit('ok') }, }, } </script>
能够看到transition
组件接收了一个name
props,那么怎么编写css
完成动画呢?很简单的方式,写出两个
关键class
(css 的 className)样式便可:ide
.slide-down-enter-active { animation: dialog-enter ease .3s; } .slide-down-leave-active { animation: dialog-leave ease .5s; } @keyframes dialog-enter { from { opacity: 0; transform: translateY(-20px); } to { opacity: 1; transform: translateY(0); } } @keyframes dialog-leave { from { opacity: 1; transform: translateY(0); } to { opacity: 0; transform: translateY(-20px); } }
就是这么简单就开发出了效果还不错的动效,注意transition
组件的name
为slide-down
,而编写的动画的关键className
为slide-down-enter-active
和slide-down-leave-active
。函数
Dialog
作MessageBox
Element的MessageBox
的使用方法以下:
this.$confirm('此操做将永久删除该文件, 是否继续?', '提示', { confirmButtonText: '肯定', cancelButtonText: '取消', type: 'warning' }).then(() => { this.$message({ type: 'success', message: '删除成功!' }); }).catch(() => { this.$message({ type: 'info', message: '已取消删除' }); });
看到这段代码,个人感受就是好神奇好神奇好神奇(惊叹三连)。仔细看看,这个组件其实就是一个封装好的dialog
,
接下来,我也要封装一个这样的组件。首先,整理下思路:
this.$confirm
,这不就是挂到Vue
的prototype
上就好了then
是肯定,catch
是取消,promise
就能够啦整理好思路,我就开始编码了:
import Vue from 'vue' import MessgaeBox from './src/index' const Ctur = Vue.extend(MessgaeBox) let instance = null const callback = action => { if (action === 'confirm') { if (instance.showInput) { instance.resolve({ value: instance.inputValue, action }) } else { instance.resolve(action) } } else { instance.reject(action) } instance = null } const showMessageBox = (tip, title, opts) => new Promise((resolve, reject) => { const propsData = { tip, title, ...opts } instance = new Ctur({ propsData }).$mount() instance.reject = reject instance.resolve = resolve instance.callback = callback document.body.appendChild(instance.$el) }) const confirm = (tip, title, opts) => showMessageBox(tip, title, opts) Vue.prototype.$confirm = confirm
至此,可能会疑惑怎么callback
呢,其实我编写了一个封装好的dialog
并将其命名为MessageBox
,
它的代码中,有这样两个方法:
onCancel() { this.visible = false this.callback && (this.callback.call(this, 'cancel')) }, onConfirm() { this.visible = false this.callback && (this.callback.call(this, 'confirm')) },
没错,就是肯定
和取消
时进行callback
。我还想说一说Vue.extend
,代码中引入了MessageBox
,
我不是直接new MessageBox
而是借助new Ctur
,由于这样能够定义数据(不单单是props)
,例如:
instance = new Ctur({ propsData }).$mount()
这时候,页面上实际上是尚未MessageBox
的,咱们须要执行:
document.body.appendChild(instance.$el)
若是你直接这样,你可能会发现MessageBox
打开的时候没有动画,而关闭的时候有动画。解决方法也很简单,appendChild
的时候让其还是不可见,而后使用类这样的代码:
Vue.nextTick(() => instance.visible = true)
这样就有动画了。
transition
和css
实现不错的动画。其中,transition
组件的name
决定了编写css
的两个关键[name]-enter-active
和[name]-leave-active
Vue.extend
继承一个组件的构造函数(不知道怎么说合适,就先这样说),而后经过这个构造函数,即可以document.body.appendChild
而后Vue.nextTick(() => instance.visible = true)
到此,简单的Vue组件开发就总结完了,我写的相关代码在地址,欢迎指正批评,求star...