Vue組件開發(fā)技巧總結
前言
臨近畢業(yè),寫了個簡單個人博客,項目地址是點我訪問項目地址(順便求star),本篇是系列總結第一篇。接下來會一步一步模仿一個低配版的Element 的對話框和彈框組件。
正文
Vue 單文件組件開發(fā)
當使用vue-cli初始化一個項目的時候,會發(fā)現(xiàn)src/components文件夾下有一個HelloWorld.vue文件,這便是單文件組件的基本開發(fā)模式。
// 注冊
Vue.component('my-component', {
template: '<div>A custom component!</div>'
})
// 創(chuàng)建根實例
new Vue({
el: '#example'
})
接下來,開始寫一個dialog組件。
Dialog
目標對話框組件的基本樣式如圖:

根據(jù)目標樣式,可以總結出:
- dialog組件需要一個titleprops來標示彈窗標題
- dialog組件需要在按下確定按鈕時發(fā)射出確定事件(即告訴父組件確定了)
- 同理,dialog組件需要發(fā)射出取消事件
- dialog組件需要提供一個插槽,便于自定義內容
那么,編碼如下:
<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組件的開發(fā),使用方法如下:
<ta-dialog title="彈窗標題" @ok="handleOk" @cancel="handleCancel"> <p>我是內容</p> </ta-dialog>
這時候發(fā)現(xiàn)一個問題,通過使用v-if或者v-show來控制彈窗的展現(xiàn)時,沒有動畫?。?!,看上去很生硬。教練,我想加動畫,這時候就該transition組件上場了。使用transition組件結合css能做出很多效果不錯的動畫。接下來增強dialog組件動畫,代碼如下:
<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組件接收了一個nameprops,那么怎么編寫css完成動畫呢?很簡單的方式,寫出兩個
關鍵class(css 的 className)樣式即可:
.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);
}
}
就是這么簡單就開發(fā)出了效果還不錯的動效,注意transition組件的name為slide-down,而編寫的動畫的關鍵className為slide-down-enter-active和slide-down-leave-active。
封裝Dialog做MessageBox
Element的MessageBox的使用方法如下:
this.$confirm('此操作將永久刪除該文件, 是否繼續(xù)?', '提示', {
confirmButtonText: '確定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$message({
type: 'success',
message: '刪除成功!'
});
}).catch(() => {
this.$message({
type: 'info',
message: '已取消刪除'
});
});
看到這段代碼,我的感覺就是好神奇好神奇好神奇(驚嘆三連)。仔細看看,這個組件其實就是一個封裝好的dialog,

接下來,我也要封裝一個這樣的組件。首先,整理下思路:
- Element的使用方法是this.$confirm,這不就是掛到Vue的prototype上就行了
- Element的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,因為這樣可以定義數(shù)據(jù)(不僅僅是props),例如:
instance = new Ctur({ propsData }).$mount()
這時候,頁面上其實是還沒有MessageBox的,我們需要執(zhí)行:
document.body.appendChild(instance.$el)
如果你直接這樣,你可能會發(fā)現(xiàn)MessageBox打開的時候沒有動畫,而關閉的時候有動畫。解決方法也很簡單,
appendChild的時候讓其仍是不可見,然后使用類這樣的代碼:
Vue.nextTick(() => instance.visible = true)
這樣就有動畫了。
總結
- 通過transition和css實現(xiàn)不錯的動畫。其中,transition組件的name決定了編寫css的兩個關鍵類名為[name]-enter-active和[name]-leave-active
- 通過Vue.extend繼承一個組件的構造函數(shù)(不知道怎么說合適,就先這樣說),然后通過這個構造函數(shù),便可以實現(xiàn)組件相關屬性的自定義(使用場景:js調用組件)
- js調用組件時,為了維持組件的動畫效果可以先document.body.appendChild 然后Vue.nextTick(() => instance.visible = true)
到此,簡單的Vue組件開發(fā)就總結完了,我寫的相關代碼在地址,https://github.com/mvpzx/elapse/tree/master/be/src/components
相關文章
Vue如何處理Axios多次請求數(shù)據(jù)顯示問題
這篇文章主要介紹了Vue如何處理Axios多次請求數(shù)據(jù)顯示問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01
vue keep-alive實現(xiàn)多組件嵌套中個別組件存活不銷毀的操作
這篇文章主要介紹了vue keep-alive實現(xiàn)多組件嵌套中個別組件存活不銷毀的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10
vue中el-table格式化el-table-column內容的三種方法
本文主要介紹了vue中el-table格式化el-table-column內容的三種方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-08-08

