手把手教你擼vue全域性元件

Code陳發表於2019-01-30

在開發vue專案時,經常會用到element UI元件,在全域性使用像message,toast,alert等元件得時候會很方便,但是在開發需要UI制定的專案時,就不能使用element UI了,這時就需要自己去開發屬於自己的元件庫了。 具體的開發方法官網提供了。下面我們就根據官網提供的方法來開發屬於我們自己的alert警告元件

  1. 首先我們要在src/components資料夾下建立一個alert資料夾,在裡面建立兩個檔案
├── src
│   ├── components
│   │   ├── alert
│   │   │   ├── alert.vue #alert元件
│   │   │   ├── index.js #外掛邏輯
複製程式碼
  1. 編寫alert元件
<template>
  <transition name="alert-fade">
    <div
      class="ht-message"
      v-if="show"
    >
      <div
        class="ht-model"
        @click="close"
      ></div>
      <div
        class="ht-message-box"
        :style="'width:'+width"
      >
        <div class="ht-message-header">
          <i
            class="iconfont icon-error ht-message-close"
            @click="close"
          ></i>
        </div>
        <div class="ht-message-body">
          {{message}}
        </div>
        <div class="ht-message-footer">
          <slot name="footer">
            <div
              class="ht-message-btn"
              @click="close"
            >
              確定
            </div>
          </slot>
        </div>
      </div>
    </div>
  </transition>
</template>

<script>
  export default {
    name: 'Alert',
    props: {
      width: {
        //彈框的寬度
        type: String,
        required: false,
        default: '30%'
      }
    },
    data() {
      return {
        show: false
      }
    },
    methods: {
      close() {
        this.show = false
        this.$el.remove() //再點選關閉得時候要將其移出,(僅在第一種方法中使用)
        this.confirmSure()
      }
    }
  }
</script>

<style scoped lang="less">
  .alert-fade-enter-active,
  .alert-fade-leave-active {
    transition: opacity 0.3s;
  }
  .alert-fade-enter,
  .alert-fade-leave-to {
    opacity: 0;
  }
  .ht-message {
    .ht-model {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      z-index: 500;
      background: rgba(0, 0, 0, 0.5);
    }
    .ht-message-box {
      position: fixed;
      top: 50%;
      left: 50%;
      z-index: 501;
      background-color: #fff;
      -webkit-transform: translate(-50%, -50%);
      -moz-transform: translate(-50%, -50%);
      -ms-transform: translate(-50%, -50%);
      -o-transform: translate(-50%, -50%);
      transform: translate(-50%, -50%);
      border-radius: 10px;
      padding: 5px 10px;
      .ht-message-body {
        text-align: center;
        font-size: 18px;
        color: #333;
      }
      .ht-message-header {
        height: 30px;
        .ht-message-close {
          float: right;
          padding: 5px 10px;
          margin: -5px -10px;
          cursor: pointer;
          color: #666;
        }
      }
      .ht-message-footer {
        width: 100%;
        .ht-message-btn {
          margin: 40px auto 30px;
          padding: 0 30px;
          width: 200px;
          height: 40px;
          font-size: 18px;
          color: #fff;
          background-color: #ff3f47;
          -webkit-border-radius: 20px;
          -moz-border-radius: 20px;
          border-radius: 20px;
          line-height: 40px;
          text-align: center;
          cursor: pointer;
        }
      }
    }
  }
</style>

複製程式碼
  1. 現在就要index.js中註冊元件並完成業務邏輯了,(==在這裡我們要注意,如果我們要在除了vue元件以外的地方使用得話,例如我們封裝的api.js裡如果需要alert某些請求狀態的時候,需要下面第一種寫法==)
import AlertComponent from './alert.vue'
import Vue from 'vue'
const Alert = (msg, confirmSure = () => {}) => {
  const Constructor = Vue.extend(AlertComponent) //建立一個alert子例項
  let instance = new Constructor({
    el: document.createElement('div'), //將alert例項掛載到建立的div上
    data() {
      return {
        message: msg, //需要顯示的資訊
        show: true //在呼叫alert時顯示元件
      }
    },
    methods: {
      confirmSure: confirmSure //點選關閉的時候觸發的回撥函式
    }
  })
  document.body.appendChild(instance.$el) //新增到body中
}

export default Alert

複製程式碼

但是如果我們只是在vue元件中使用的話,使用下面第二種註冊方法

import AlertComponent from './alert.vue'

const Alert = {
  install(Vue) {
    const Constructor = Vue.extend(AlertComponent) //建立一個alert子例項
    let instance = new Constructor({
      el: document.createElement('div') //將alert例項掛載到建立的div上
    })
    document.body.appendChild(instance.$el) //新增到body中
    //繫結到vue原型上,以供全域性使用
    Vue.prototype.$alert = (msg, confirmSure = () => {}) => {
      instance.message = msg //需要顯示的資訊
      instance.show = true //在呼叫alert時顯示元件
      instance.confirmSure = confirmSure //點選關閉的時候觸發的回撥函式
    }
  }
}

export default Alert

複製程式碼
  1. 最後我們在main.js引入的時候也需要注意,如果我們要在元件和元件以外的情況下使用alert的話,我們需要這樣引入
import Alert from '@/components/alert'
Vue.prototype.$alert = Alert
複製程式碼

再如果我們只是在vue元件裡使用的話,我們要這樣引入

import Alert from '@/components/alert'
Vue.use(Alert)
複製程式碼
  1. 最後我們就可以愉快的呼叫元件了
//呼叫方法(元件以外的呼叫方式)
import Alert from '@/components/alert'
Alert('使用者會話過期,請重新登入', () => {
    console.log('我被呼叫了')
})
元件內使用
this.$alert('使用者會話過期,請重新登入', () => {
    console.log('我被呼叫了')
})
複製程式碼

相關文章