臨近畢業,寫了個簡單我的博客,項目地址是點我訪問項目地址(順便求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...