如何實現一個經過js調用使用的消息提示組件(Vue)

在項目開發過程當中可能咱們習慣了使用各類現成的UI庫,它能夠幫助咱們快速的完成項目開發,例如咱們在項目中常常使用到的Toast、Message提示組件,咱們一般只須要經過js來調用就可使用了,和咱們日常使用組件的方式(import導入、components註冊)並不同,那接下來咱們就本身來實現一個經過js方法來使用的組件。咱們最後要實現的組件就是element-UI的Message消息提示vue

1、準備工做

咱們首先在項目中新建一個文件夾來存放這個組件,我建在了/src/components/Message/,很顯然Message就是我放提示組建的目錄。api

接着咱們在Message下再建一個index.vueindex.js的文件,js是咱們組件的入出口也是用來導出方法被調用的主體。bash

2、編寫組件模板

咱們先寫一個基礎的樣式,而後經過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$mountappendChild三個api,那咱們就看下這三個API到底作了什麼flex

  1. extend是Vue的一個全局api,它接收一個包含組件選項的對象,例如這個樣子(官方示例)
Vue.extend({
  template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
  data: function () {
    return {
      firstName: 'Walter',
      lastName: 'White',
      alias: 'Heisenberg'
    }
  }
})
複製代碼

而後extend會建立一個Vue‘子類’(猜想就是一個沒有被實例化的Vue組件)優化

  1. $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);
}
複製代碼
  1. appendChild: 至此就很容易理解了,最後將組件加入到body主體中渲染出來
  2. 最後使用的時候調用$message方法,沒什麼說的。

很關鍵的內容都在這裏。那麼接下來咱們就再實現個東西,Element-UI的這個組件是能夠傳入自定義消息內容的,也能夠傳入不一樣的type來顯示成功或警告樣式的消息,更進一步,好比咱們須要在消息關閉的時候來作別的操做,又要如何處理呢?ui

3、組件完善

1. 自定義組件內容

  • 修改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: '對不起,註冊失敗'});
複製代碼

2. 增長提示關閉按鈕,提示被關閉後調用者能夠感知

  • 修改index.vue代碼
<template>
  <div class="message">
    <p>{{message}}</p>
    <i class="close" @click="handleClose">&times;</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('組件被關閉了');
    },
});
複製代碼

4、補充

至此其實咱們講這個組件的目的已經完成了,就是告訴你如何經過js來使用」消息提示「這類的組件,其他的成功失敗警告定時關閉等功能,就不一一實現了,時間空閒的各位能夠自行實現一下。spa

若是這篇文章對你有做用還望不吝點個贊,若是有其餘疑問或內容有誤能夠在評論留言指正啊。拜拜!

相關文章
相關標籤/搜索