在項目開發過程當中可能咱們習慣了使用各類現成的UI庫,它能夠幫助咱們快速的完成項目開發,例如咱們在項目中常常使用到的Toast、Message提示組件,咱們一般只須要經過js來調用就可使用了,和咱們日常使用組件的方式(import導入、components註冊)並不同,那接下來咱們就本身來實現一個經過js方法來使用的組件。咱們最後要實現的組件就是element-UI的Message消息提示vue
咱們首先在項目中新建一個文件夾來存放這個組件,我建在了/src/components/Message/
,很顯然Message就是我放提示組建的目錄。api
接着咱們在Message
下再建一個index.vue
和index.js
的文件,js是咱們組件的入出口也是用來導出方法被調用的主體。bash
咱們先寫一個基礎的樣式,而後經過js調用渲染出來,以後咱們在對組件進行細節優化app
index.vue
內容<template>
<div class="message">
<p>這是一條消息提示</p>
</div>
</template>
<script>
export default {
name: 'Message'
}
</script>
<style scoped lang="stylus">
.message
position fixed
top 3vh
left 50vw
transform translateX(-50%)
border 1px solid #EBEEF5
background-color #edf2fc
min-width 340px
min-height 50px
display flex
align-items center
box-sizing border-box
padding 0 15px
border-radius 5px
</style>
複製代碼
index.js
內容import Vue from 'vue';
import Message from './index.vue';
const MessageConstructor = Vue.extend(Message);
export const $message = () => {
const instance = new MessageConstructor().$mount();
document.body.appendChild(instance.$el);
}
複製代碼
$message
方法使用<script>
import { $message } from '@/components/Message/index';
export default {
name: 'home',
mounted() {
// 正常應該在點擊按鈕或者某些操做執行後調用,我這裏爲了直觀顯示就在生命週期內調用了
$message();
}
}
</script>
複製代碼
index.vue
中是咱們編寫組件的代碼,和咱們正常編寫Vue組件使一毛同樣的。咱們之因此能夠經過調用js方法來使用組件,最關鍵的代碼是在index.js
中。函數
index.js
中只有7行代碼,看一眼,很容易猜到最核心的確定就是extend
、$mount
和appendChild
三個api,那咱們就看下這三個API到底作了什麼flex
Vue.extend({
template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
data: function () {
return {
firstName: 'Walter',
lastName: 'White',
alias: 'Heisenberg'
}
}
})
複製代碼
而後extend會建立一個Vue‘子類’(猜想就是一個沒有被實例化的Vue組件)優化
$mount
:若是咱們對extend
建立的子類進行實例化的時候沒有傳入 el 選項,那此時這個組件就處於未掛載的狀態,咱們就須要調用$mount
方法,手動將其掛載,$mount
方法若是沒有傳入參數,那麼它掛載後會自動關聯此組件的頂層元素,若是傳入參數(能夠接收元素、元素選擇器)則關聯傳入的元素。基於此其實咱們也能夠不調用$mount
方法,在實例化的時候傳入el選項;import Vue from 'vue';
import Message from './index.vue';
const MessageConstructor = Vue.extend(Message);
export const $message = () => {
const instance = new MessageConstructor({
el: document.createElement('div'),
});
document.body.appendChild(instance.$el);
}
複製代碼
$message
方法,沒什麼說的。很關鍵的內容都在這裏。那麼接下來咱們就再實現個東西,Element-UI的這個組件是能夠傳入自定義消息內容的,也能夠傳入不一樣的type
來顯示成功或警告樣式的消息,更進一步,好比咱們須要在消息關閉的時候來作別的操做,又要如何處理呢?ui
index.js
代碼import Vue from 'vue';
import Message from './index.vue';
const MessageConstructor = Vue.extend(Message);
// 方法接收個options參數,options必須是object類型
export const $message = (options) => {
const instance = new MessageConstructor({
el: document.createElement('div'),
// 組件實例生成的時候在給組件動態傳入data
data: options
});
document.body.appendChild(instance.$el);
}
複製代碼
index.vue
代碼<template>
<div class="message">
// 內容改成可變的
<p>{{message}}</p>
</div>
</template>
<script>
export default {
name: 'Message',
// data是新增的
data() {
return {
message: '',
}
}
}
</script>
<style scoped lang="stylus">
.message
position fixed
top 3vh
left 50vw
transform translateX(-50%)
border 1px solid #EBEEF5
background-color #edf2fc
min-width 340px
min-height 50px
display flex
align-items center
box-sizing border-box
padding 0 15px
border-radius 5px
</style>
複製代碼
$message({message: '對不起,註冊失敗'});
複製代碼
index.vue
代碼<template>
<div class="message">
<p>{{message}}</p>
<i class="close" @click="handleClose">×</i>
</div>
</template>
<script>
export default {
name: 'Message',
data() {
return {
message: '',
}
},
methods: {
emitClose() {},
handleClose() {
this.$el.parentNode.removeChild(this.$el);
this.emitClose();
}
}
}
</script>
<style scoped lang="stylus">
.message
position fixed
top 3vh
left 50vw
transform translateX(-50%)
border 1px solid #EBEEF5
background-color #edf2fc
min-width 340px
max-width 500px
min-height 50px
display flex
align-items center
justify-content space-between
box-sizing border-box
padding 0 15px
border-radius 5px
.close
font-size 25px
align-self flex-start
margin-top -5px
margin-right -9px
cursor pointer
</style>
複製代碼
index.js
代碼import Vue from 'vue';
import Message from './index.vue';
const MessageConstructor = Vue.extend(Message);
export const $message = (options,methods = {}) => {
const instance = new MessageConstructor({
el: document.createElement('div'),
data: options,
methods
});
document.body.appendChild(instance.$el);
}
複製代碼
$message({message: '對不起,註冊失敗對不起'}, {
emitClose() {
console.log('組件被關閉了');
},
});
複製代碼
TIP: 若是關閉的時候但願被調用者能夠被感知,除了傳methods,其實也能夠直接傳入data,不過傳入的就是一個函數,相似於this
$message({
message: '對不起,註冊失敗對不起',
onClose() {
console.log('組件被關閉了');
},
});
複製代碼
至此其實咱們講這個組件的目的已經完成了,就是告訴你如何經過js來使用」消息提示「這類的組件,其他的成功、失敗、警告、定時關閉等功能,就不一一實現了,時間空閒的各位能夠自行實現一下。spa
若是這篇文章對你有做用還望不吝點個贊,若是有其餘疑問或內容有誤能夠在評論留言指正啊。拜拜!