仿寫vue UI 組件總結 (本身練習,仿照現有的UI組件)

UI組件
Vue開發插件流程
原本是昨天要寫總結的,感受本身寫很差,就放棄了。今天看到了iview和element有一些摩擦,是關於代碼借鑑的問題(哈哈),不作評價。誰下生會寫組件,我仿(chao)寫了radonUI,這個組件體量比較小,好仿寫。就是以這個爲切入口寫UI組件,先本身寫,而後在仿寫。看看別人寫的好比bootstrap,這樣提升挺快的。其實UI組件套路差很少,寫過一遍就有感受了。不像之前沒想法、沒思路。html

概述

大部分組件我都寫了一遍,剩下的要參考iview和element組件。這些組件中表格、表單、tree仍是比較有難度的,前倆個尚未實踐。下面是個人總結vue

全局插件notification

  1. 思考:在全局組件中要作到像window.alert()同樣調用,在代碼任何的地方調用,就有收集‘調用結果’的地方。
  2. 這時候插件思想就出現了,就像把alert寫在window上,把調用的方法寫在Vue上

代碼:git

// plugins.js

import Vue from 'vue'
import Notification  from './Notification.js'

export default {

    // install是Vue寫插件固有方法
    install: function (Vue, {
        notification=true
    }={}) {
        if ( notification ) {
            Notification(Vue);
        }
  }
};

{notification=true}={}
是options,寫插件的時候能夠提供這個選項,他的做用決定組件是否自動加載。這樣的調用插件能夠github

import myPlugin from './plugins/plugins.js'
Vue.use(myPlugin)

若是{notification=false}={}就改變調用方式bootstrap

import myPlugin from './plugins/plugins.js'
Vue.use(myPlugin, {
  notification: true
})
// Notification.js

import Vue from 'vue'
import { olNotification } from "../components/index"

// 註冊全局的組件
// 建立一個div 把olNotification組件掛在到div中,就能夠調用組件中方法了,把‘調用結果’放到組件(olNotification)中,來展現視圖

const div = document.createElement('div');
div.innerHTML = `<ol-notification></ol-notification>`;
document.body.appendChild(div);
const notification = new Vue({
    el: div,
    components: { olNotification }
}).$children[0];


export default function() {
    Vue.prototype.$Notification = {
        remove (item, duration){
            setTimeout(() => {
                notification.closeItem(item)
            }, duration)
        },
        create(type, title, content, duration){
            let data = {
                title,
                content,
                duration
            }

            // 把‘調用結果’放到組件
            notification.addItem(data)
            if(duration){

                // 一段時間(duration)把‘調用結果’移除組件
                this.remove(data, duration)
            }
        },

        // 四種組件形態
        success (title, content, duration) {
            this.create('success', title, content, duration)
        },
        info (title, content, duration) {
            this.create('info', title, content, duration)
        },
        warning (title, content, duration) {
            this.create('warning', title, content, duration)
        },
        failed (title, content, duration) {
            this.create('failed', title, content, duration)
        }
    }
}
// olNotification.vue
<style  lang = "sass" >
.ol-notification-container {
    position: fixed;
    top: 1rem;
    right: 1rem;
    z-index: 9999;
}  
.ol-notification{
    position: relative;
    width: 20rem;
    background-color: #fff;
    margin-right: 1rem;
    border: 1px solid #eaf8fe;
    border-radius: 4px;
    padding: 1rem 1.5rem;
    margin-bottom: 1rem;
    &.success,
    &.warning,
    &.failed,
    &.info {
        padding-left: 4rem;
    }
    &.success {
        .rd-notification-icon {
            color: #87d068;
        }
    }
    &.info {
        .rd-notification-icon {
            color: #2db7f5;
        }
    }
    &.warning {
        .rd-notification-icon {
            color: #fa0;
        }
    }
    &.failed {
        .rd-notification-icon {
            color: #f50;
        }
    }
}
.ol-notification-title {
    font-size: .9rem;
}
.ol-notification-content {
    color: #999;
    font-size: .8rem;
    line-height: 1.5;
    margin: 0;
}
.ol-notification-close {
    position: absolute;
    top: .2rem;
    right: .5rem;
    font-size: .8rem;
    color: #ccc;
}
.ol-notification-close:hover {
    color: #969696;
}
.ol-notification-icon{
    position: absolute;
    top: 50%;
    font-size: 1.5rem;
    left: 1rem;
    margin-top: -.75rem;
    line-height: 1.5rem;
}
.notification-enter {
    opacity: 0;
}
.notification-enter-active, .notification-leave  {
    transition: opacity .5s ease;
}
.notification-leave-active {
    opacity: 0;
    position: absolute;
}
.notification-move {
    transition: transform .5s cubic-bezier(.55,0,.1,1);
}
</style>
<template>
    <div class="ol-notification-container" >
        <transition-group  name="notification">
            <div 
                class="ol-notification"
                v-for="(item, index) in allItem"
                v-bind:key="item"
            >
                <span class="ol-notification-title">{{item.title}}</span>
                <p class="ol-notification-content">{{item.content}}</p>
                <span class="ol-notification-close    ion-close-round" @click="closeItem(item)"></span>
            </div>
        </transition-group >
    </div>
</template>
<script>
export default {
    computed: {
    },
    components: { 
    },
    data () {
        return {
            allItem: []
        }
    },
    mounted() {
    },
    methods:{
        closeItem (item) {
            this.allItem = this.allItem.filter(function(current) {
                return current !== item
            })
        },
        addItem (item) {
            this.allItem.push(item);
        }
    }
}
</script>

createObjectURL

window.URL.createObjectURL(blob|| file) 方法會根據傳入的參數建立一個指向該對象的URL,這個URL 的生命週期僅僅存在於被建立的文檔裏面新的對象URL指向執行的File對象或者是Blob對象.瀏覽器

File對象或者Blob對象sass

這裏大概說下File對象和Blob對象:app

File對象,就是一個文件,好比我用input type="file"標籤來上傳文件,那麼裏面的每一個文件都是一個File對象.iview

Blob對象,就是二進制數據,好比經過new Blob()建立的對象就是Blob對象.又好比,在XMLHttpRequest裏,若是指定responseType爲blob,那麼獲得的返回值也是一個blob對象.性能

注意點:

每次調用createObjectURL的時候,一個新的URL對象就被建立了.即便你已經爲同一個文件建立過一個URL. 若是你再也不須要這個對象,要釋放它,須要使用URL.revokeObjectURL()方法. 當頁面被關閉,瀏覽器會自動釋放它,可是爲了最佳性能和內存使用,當確保再也不用獲得它的時候,就應該釋放它.

二.URL.revokeObjectURL

URL.revokeObjectURL()方法會釋放一個經過URL.createObjectURL()建立的對象URL. 當你要已經用過了這個對象URL,而後要讓瀏覽器知道這個URL已經再也不須要指向對應的文件的時候,就須要調用這個方法.

具體的意思就是說,一個對象URL,使用這個url是能夠訪問到指定的文件的,可是我可能只須要訪問一次,一旦已經訪問到了,這個對象URL就再也不須要了,就被釋放掉,被釋放掉之後,這個對象URL就再也不指向指定的文件了.

好比一張圖片,我建立了一個對象URL,而後經過這個對象URL,我頁面里加載了這張圖.既然已經被加載,而且不須要再次加載這張圖,那我就把這個對象URL釋放,而後這個URL就再也不指向這張圖了.

相關文章
相關標籤/搜索