手寫一個Vue版Toast組件

前言

目前,前端生態圈中各大廠高大尚的UI庫比比皆是。可是做爲一名業務中都是接觸移動端開發、H5開發的搬磚者,面對產品各類高端霸氣上檔次的需求,996是在所不辭的。javascript

因此該如何減小本身的工做壓力?

  1. 工做中養成對本身代碼覆盤的習慣,各式各樣經常使用到的設計均可以抽離出來做爲公共使用的插件或者組件。這樣在後續遇到一樣問題時,Ctrl+C、Ctrl+V複製粘貼使用是能快速完成問題的,可是不利於代碼的可閱讀性。正所謂一時抽離一時爽,後續使用一直爽。
  2. 也能夠選擇忽悠產品改需求,也能夠選擇閱讀UI庫源碼改動源碼來適配需求。正所謂條條大路通羅馬,我更傾向擁有本身一套邏輯思惟的設計,自行改動的時候也更加快速。

個人第N個Vue組件,Toast

1.組件設計

對外暴露方法 info success errer warning closehtml

API前端

參數 說明 類型 可選值 默認值
context 提示的內容 String
duration 關閉時間 Number 3000
icon 可自定義的icon String
mask 是否開啓遮罩層 Boolean false/true false
clear Toast關閉回調 Function

2.實現

1.對外暴露調用方法
//index.js

const type = ["success", "errer", "warning"]
const fnc = {
    name: 'G-Toast',
    info: (options = {}) => {
        
    },
    close: () => {
        if (install) {
            
        }
    }
}
type.forEach(element => {
    fnc[element] = (options = {}) => {
        
    }
});

export default fnc
複製代碼
2.視圖實現
<!--index.vue-->

<template>
  <div class="g7-Toast">
    <template v-if="mask">
      <transition name="fade">
        <div v-show="value" class="g7-Toast-mask"></div>
      </transition>
    </template>
    <transition name="fade">
      <div v-show="value" :class="['g7-Toast-body',type]">
        <div class="g7-Toast-iconfont" v-show="type">
          <Icon :icon="iconfont" :size="26" color="#fff" />
        </div>
        <div class="g7-Toast-context">{{context}}</div>
      </div>
    </transition>
  </div>
</template>

<script> import Icon from "../Icon"; export default { components: { Icon }, props: { type: { type: String, validator: function(value) { return ["success", "errer", "warning", "loading"].includes(value); } }, value: { type: Boolean }, context: { type: String }, icon: { type: String }, mask: { type: Boolean, default: false } }, computed: { iconfont() { if (this.icon) { return this.icon; } const icon = { success: "iconzhengque", errer: "iconcuowu", warning: "iconinfo", loading: "" }; return icon[this.type]; } } }; </script>
複製代碼
3.建立實例Vue,渲染視圖
//index.js

import Vue from "vue";
import Toast from "./index.vue";

let install;

function newInstall(options) {
    install = new Vue({
        data() {
            return options;
        },
        render(h) {
            return h(Toast, {
                props: {
                    value: this.value,
                    context: this.context,
                    type: this.type,
                    icon: this.icon,
                    mask: this.mask
                }
            })
        }
    })
    if (window) {
        document.body.appendChild(install.$mount().$el)
    }
}
複製代碼

小提示:配置jsx在render函數中寫渲染函數會更爽vue

4.增長調用視圖方法
// index.js

let timer;

function init(options, type) {
    const params = {
        value: undefined,
        context: undefined,
        type: undefined,
        duration: 3000,
        icon: undefined,
        mask: undefined,
        clear: () => { }
    }
    if (!install) {
        newInstall(params)
    }
    Object.assign(install, params, options, { value: true, context: options.context ? options.context : options, type: type })
    if (install.duration > 0) {
        clearTimeout(timer);
        timer = setTimeout(function () {
            Object.assign(install, { value: false })
            install.clear()
        }, install.duration);
    }
}
複製代碼
5.最後更新代碼對外暴露調用方法
//index.js

const type = ["success", "errer", "warning"]
const fnc = {
    name: 'G-Toast',
    info: (options = {}) => {
        init(options)
    },
    close: () => {
        if (install) {
            Object.assign(install, { value: false })
            install.clear()
        }
    }
}
type.forEach(element => {
    fnc[element] = (options = {}) => {
        init(options, element)
    }
});

export default fnc
複製代碼

效果圖

總結

本人水平有限,搬磚不易,不足之處請多指教!
各類各樣的業務組件通過內部業務的打磨後,會慢慢整理共享給各位大佬......java

相關文章
相關標籤/搜索