We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
本文接下来会一步一步模仿造一个低配版的 Element 的对话框和弹框组件。
Element 的对话框和弹框组件
当使用vue-cli初始化一个项目的时候,会发现 src/components 文件夹下有一个 HelloWorld.vue 文件,这便是单文件组件的基本开发模式。
vue-cli
src/components
HelloWorld.vue
// 注册 Vue.component("my-component", { template: "<div>A custom component!</div>" }); // 创建根实例 new Vue({ el: "#example" });
接下来,开始写一个 dialog 组件。
dialog
目标对话框组件的基本样式如图:
根据目标样式,可以总结出:
title
确定
发射
取消
那么,编码如下:
<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组件的开发,使用方法如下:
<ta-dialog title="弹窗标题" @ok="handleOk" @cancel="handleCancel"> <p>我是内容</p> </ta-dialog>
这时候发现一个问题,通过使用 v-if 或者 v-show 来控制弹窗的展现时,没有动画!!!,看上去很生硬。教练,我想加动画 ,这时候就该 transition 组件上场了。使用 transition 组件结合 css能做出很多效果不错的动画。接下来增强 dialog 组件动画,代码如下:
v-if
v-show
教练,我想加动画
transition
css
<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)样式即可:
name
class
.slide-down-enter-active { animation: dialog-enter ease 0.3s; } .slide-down-leave-active { animation: dialog-leave ease 0.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 。
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 , 它的代码中,有这样两个方法:
callback
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),例如:
Vue.extend
new MessageBox
new Ctur
定义数据(不仅仅是props)
instance = new Ctur({ propsData }).$mount();
这时候,页面上其实是还没有MessageBox的,我们需要执行:
document.body.appendChild(instance.$el);
如果你直接这样,你可能会发现 MessageBox 打开的时候没有动画,而关闭的时候有动画。解决方法也很简单, appendChild的时候让其仍是不可见,然后使用类这样的代码:
appendChild
Vue.nextTick(() => (instance.visible = true));
这样就有动画了。
[name]-enter-active
[name]-leave-active
document.body.appendChild
Vue.nextTick(() => instance.visible = true)
The text was updated successfully, but these errors were encountered:
No branches or pull requests
前言
本文接下来会一步一步模仿造一个低配版的
Element 的对话框和弹框组件
。正文
Vue 单文件组件开发
当使用
vue-cli
初始化一个项目的时候,会发现src/components
文件夹下有一个HelloWorld.vue
文件,这便是单文件组件的基本开发模式。接下来,开始写一个
dialog
组件。Dialog
目标对话框组件的基本样式如图:
根据目标样式,可以总结出:
title
props 来标示弹窗标题确定
按钮时发射
出确定
事件(即告诉父组件确定
了)发射
出取消
事件那么,编码如下:
这样便完成了
dialog
组件的开发,使用方法如下:这时候发现一个问题,通过使用
v-if
或者v-show
来控制弹窗的展现时,没有动画!!!,看上去很生硬。教练,我想加动画
,这时候就该transition
组件上场了。使用transition
组件结合css
能做出很多效果不错的动画。接下来增强dialog
组件动画,代码如下:可以看到
transition
组件接收了一个name
props,那么怎么编写css
完成动画呢?很简单的方式,写出两个关键
class
(css 的 className)样式即可:就是这么简单就开发出了效果还不错的动效,注意
transition
组件的name
为slide-down
,而编写的动画的关键className
为slide-down-enter-active
和slide-down-leave-active
。封装
Dialog
做MessageBox
Element 的
MessageBox
的使用方法如下:看到这段代码,我的感觉就是好神奇好神奇好神奇(惊叹三连)。仔细看看,这个组件其实就是一个封装好的
dialog
,接下来,我也要封装一个这样的组件。首先,整理下思路:
this.$confirm
,这不就是挂到Vue
的prototype
上就行了then
是确定,catch
是取消,promise
就可以啦整理好思路,我就开始编码了:
至此,可能会疑惑怎么
callback
呢,其实我编写了一个封装好的dialog
并将其命名为MessageBox
,它的代码中,有这样两个方法:
没错,就是
确定
和取消
时进行callback
。我还想说一说Vue.extend
,代码中引入了MessageBox
,我不是直接
new MessageBox
而是借助new Ctur
,因为这样可以定义数据(不仅仅是props)
,例如:这时候,页面上其实是还没有
MessageBox
的,我们需要执行:如果你直接这样,你可能会发现
MessageBox
打开的时候没有动画,而关闭的时候有动画。解决方法也很简单,appendChild
的时候让其仍是不可见,然后使用类这样的代码:这样就有动画了。
总结
transition
和css
实现不错的动画。其中,transition
组件的name
决定了编写css
的两个关键类名为
[name]-enter-active
和[name]-leave-active
Vue.extend
继承一个组件的构造函数(不知道怎么说合适,就先这样说),然后通过这个构造函数,便可以实现组件相关属性的自定义(使用场景:js 调用组件)
document.body.appendChild
然后Vue.nextTick(() => instance.visible = true)
The text was updated successfully, but these errors were encountered: