日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

uni-app中怎么開發(fā)一個全局彈層組件?下面本篇文章給大家通過例子介紹一下uni-app中實(shí)現(xiàn)一個全局彈層組件的方法,希望對大家有所幫助!


uni-app中怎么開發(fā)一個全局彈層組件(代碼示例)


公司有一個采用uni-app框架寫的app應(yīng)用,里面的彈層基本是使用官方的uni.showModal之類的api實(shí)現(xiàn)彈層,在設(shè)備上表現(xiàn)就是原生的彈層,在客戶的要求下,需要更換成設(shè)計的樣式,所以就開始實(shí)現(xiàn)這樣一個組件。

根據(jù)彈層經(jīng)常使用的方法和方式可以大致列出他需要的屬性和方法:

類型:alert/confirm

展示圖標(biāo) icon

展示內(nèi)容 content

可以api調(diào)用

支持promise,可以使用$api.xx().then

前幾項就很好做,就在data中定義好字段,外層直接拿官方的輪子uni-popup,這樣少寫一些控制彈出的邏輯(懶的),這樣大致結(jié)構(gòu)就寫好了

// template部分
<uni-popup ref="popup" :maskClick="maskClick">
    <view class="st-layer" :style="{ width: width }">
        <view class="st-layer__content">
            <!-- #ifndef APP-NVUE -->
            <text class="st-layer__icon" :class="option.iconClass || getIconClass()"
                v-if="option.type !== 'none' && option.showIcon"></text>
            <!-- #endif -->
            <view class="st-layer__msg" v-if="option.msg">
                <text>{{ option.msg }}</text>
            </view>
        </view>
        <view class="st-layer__footer" :class="{'is-reverse-cofirmcancel' : isReverseConfirmCancel}" v-if="option.showConfirmButton || option.showCancelButton">
            <view class="st-layer__footer__btn st-layer__footer__btn--confirm" @tap.stop="confirmClick"
                v-if="option.showConfirmButton"><text>確認(rèn)</text></view>
            <view class="st-layer__footer__btn st-layer__footer__btn--cancel" @tap.stop="cancelClick"
                v-if="option.showCancelButton"><text>取消</text></view>
        </view>
    </view>
</uni-popup>

然后js部分先簡單實(shí)現(xiàn)了一些open和close方法

data() {
    return {
            option: {}
    }
},
methods: {
    open(option) {
        let defaultOption = {
                showCancelButton: false, // 是否顯示取消按鈕
                cancelButtonText: '取消', // 取消按鈕文字
                showConfirmButton: true, // 是否顯示確認(rèn)按鈕
                confirmButtonText: '取消', // 確認(rèn)按鈕文字
                showIcon: true, // 是否顯示圖標(biāo)
                iconClass: null, // 圖標(biāo)class自定義
                type: 'none', // 類型
                confirm: null, // 點(diǎn)擊確認(rèn)后的邏輯
                cancel: null, // 點(diǎn)擊取消后的邏輯
                msg: ''
        }
        this.option = Object.assign({}, defaultOption, option)
        this.$refs.popup.open()
    },
    close() {
            this.$refs.popup.close()
    },
    confirmClick() {
            const confirmHandler = this.option.confirm
            if (confirmHandler && typeof confirmHandler === 'function') {
                    confirmHandler()
            }
            this.close()
            this.$emit('confirm')
    },
    cancelClick() {
            const cancelHandler = this.option.cancel
            if (cancelHandler && typeof cancelHandler === 'function') {
                    cancelHandler()
            }
            this.close()
            this.$emit('cancel')
    }
}

目前在其他頁面已經(jīng)可以使用

// test.vue  可以使用uni-app的 [easycom組件規(guī)范](https://uniapp.dcloud.io/component/README?id=easycom%e7%bb%84%e4%bb%b6%e8%a7%84%e8%8c%83),不用寫import語句
<st-layer ref="stLayer"></st-layer>
// js部分
this.$refs.stLayer.open({
    msg: '測試',
    confirm: () => {
        console.log('點(diǎn)擊了確認(rèn)')
    },
    cancel: () => {
        console.log('點(diǎn)擊了取消')
    }
})

現(xiàn)在基本功能已經(jīng)實(shí)現(xiàn),但是有人要說了,這樣調(diào)用不方便,我想這樣調(diào)用

open(msg).then(() => {
    console.log('點(diǎn)擊了確認(rèn)')
}).catch(() => {
     console.log('點(diǎn)擊了取消')
})

那如何實(shí)現(xiàn)promise化呢?最簡單的方法就是讓open方法返回一個promise。如何點(diǎn)擊確認(rèn)或取消的時候進(jìn)入then方法呢,看下面的寫法

...
open() {
     return new promise((reoslve, reject) => {
        ...
        this.option.confirm = this.option.confirm || function confirmResolve () {
            resolve()
        }
         this.option.cancel = this.option.cancel || function cancelReject () {
            reject()
        }
     })
 }
...

如果要封裝其他單獨(dú)的方法,比如confirm之類,可以在open基礎(chǔ)上擴(kuò)展:

confirm(msg, option = {}) {
        if (typeof msg === 'object') {
                option = msg
        } else {
                option.msg = msg
        }
        return this.open({
                ...option,
                showCancelButton: true,
                type: 'confirm'
        })
}
// 調(diào)用方式
this.$refs.stLayer.confirm('是否確認(rèn)?').then().catch()

這樣基本的彈層組件已經(jīng)實(shí)現(xiàn)。下面也就是最后一步全局使用原有vue項目寫的layer組件要全局使用通常是采用下面的方法注入到頁面中

import main from './main.vue'
 
const LayerConstructor = vue.extend(main)
 
const initInstance = () => {
  instance = new LayerConstructor({
    el: document.createElement('div')
  })
 
  instance.callback = defaultCallback
  document.getElementById('app').appendChild(instance.$el)
}

直接拉過來用,結(jié)果報錯,提示error: document is undefined,才想起uni-app跟普通vue項目的有一個很大的區(qū)別,在它的運(yùn)行原理中有介紹:

uni-app 邏輯層和視圖層分離,在非H5端運(yùn)行時,從架構(gòu)上分為邏輯層和視圖層兩個部分。邏輯層負(fù)責(zé)執(zhí)行業(yè)務(wù)邏輯,也就是運(yùn)行js代碼,視圖層負(fù)責(zé)頁面渲染。雖然開發(fā)者在一個vue頁面里寫js和css,但其實(shí),編譯時就已經(jīng)將它們拆分了。邏輯層是運(yùn)行在一個獨(dú)立的jscore里的,它不依賴于本機(jī)的webview,所以一方面它沒有瀏覽器兼容問題,可以在Android4.4上跑es6代碼,另一方面,它無法運(yùn)行window、document、navigator、localstorage等瀏覽器專用的js API。

所以這種注冊全局的方法已經(jīng)不可用。那該如何在uni-app中實(shí)現(xiàn)呢? 翻看官方論壇,找到了一個實(shí)現(xiàn)loadervue-inset-loader,實(shí)現(xiàn)原理就是獲取sfc模板內(nèi)容,在指定位置插入自定義內(nèi)容(也就是需要全局的組件),使用方式如下:

// 第一步
npm install vue-inset-loader --save-dev 
// 第二步 在vue.config.js(hbuilderx創(chuàng)建的項目沒有的話新建一個)中注入loader
module.export = {
    chainWebpack: config => {
            // 超級全局組件
            config.module
                    .rule('vue')
                    .test(/\.vue$/)
                    .use()
                    .loader(path.resolve(__dirname, "./node_modules/vue-inset-loader"))
                    .end()
    } 
}
// 支持自定義pages.json文件路徑  
// options: {  
//     pagesPath: path.resolve(__dirname,'./src/pages.json')  
// } 
// 第三步 pages.json配置文件中添加insetLoader
"insetLoader": {  
    "config":{  
        "confirm": "<BaseConfirm ref='confirm'></BaseConfirm>",  
        "abc": "<BaseAbc ref='BaseAbc'></BaseAbc>" 
    },  
    // 全局配置  
    "label":["confirm"],  
    "rootEle":"div" 
}

配置說明

config (default: {})

定義標(biāo)簽名稱和內(nèi)容的鍵值對

label(default: [])

需要全局引入的標(biāo)簽,打包后會在所有頁面引入此標(biāo)簽

rootEle(default: "div")

根元素的標(biāo)簽類型,缺省值為div,支持正則,比如匹配任意標(biāo)簽 ".*"

label 和 rootEle 支持在單獨(dú)頁面的style里配置,優(yōu)先級高于全局配置

到這,該組件就可以全局使用了,不需要在每個頁面寫標(biāo)簽使用,只需要調(diào)用api就可以。

后面可以再根據(jù)使用情況進(jìn)行優(yōu)化處理。水平有限,歡迎各位大佬指點(diǎn)。



分享到:
標(biāo)簽:uni-app 全局彈層組件 代碼示例
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定