Home > Web Front-end > uni-app > body text

How to develop a global elastic layer component in uni-app (code example)

青灯夜游
Release: 2022-03-07 19:59:58
forward
5509 people have browsed it

How to develop a global elastic layer component in uni-app? The following article will introduce to you through examples how to implement a global elastic layer component in uni-app. I hope it will be helpful to you!

How to develop a global elastic layer component in uni-app (code example)

The company has an app written using the uni-app framework. The elastic layer inside is basically implemented using the official uni.showModal API. , the performance on the device is the native elastic layer. At the customer's request, it needs to be replaced with the designed style, so we started to implement such a component.

According to the methods and methods often used by the elastic layer, the properties and methods it needs can be roughly listed:

  • Type: alert/confirm, etc.
  • Display icon icon
  • Display content content
  • Can be called by api
  • Supports promise, can use $api. xx().then

The first few items are easy to do, just define the fields in data, and directly use the official wheeluni in the outer layer -popup, so you need to write less logic for controlling pop-up (lazy), so that the general structure is written

// 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 !== &#39;none&#39; && 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="{&#39;is-reverse-cofirmcancel&#39; : 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>确认</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>
Copy after login

Then the js part first simply implements some open and close methods

data() {
    return {
            option: {}
    }
},
methods: {
    open(option) {
        let defaultOption = {
                showCancelButton: false, // 是否显示取消按钮
                cancelButtonText: &#39;取消&#39;, // 取消按钮文字
                showConfirmButton: true, // 是否显示确认按钮
                confirmButtonText: &#39;取消&#39;, // 确认按钮文字
                showIcon: true, // 是否显示图标
                iconClass: null, // 图标class自定义
                type: &#39;none&#39;, // 类型
                confirm: null, // 点击确认后的逻辑
                cancel: null, // 点击取消后的逻辑
                msg: &#39;&#39;
        }
        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 === &#39;function&#39;) {
                    confirmHandler()
            }
            this.close()
            this.$emit(&#39;confirm&#39;)
    },
    cancelClick() {
            const cancelHandler = this.option.cancel
            if (cancelHandler && typeof cancelHandler === &#39;function&#39;) {
                    cancelHandler()
            }
            this.close()
            this.$emit(&#39;cancel&#39;)
    }
}
Copy after login

Currently available on other pages

// test.vue  可以使用uni-app的 [easycom组件规范](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: &#39;测试&#39;,
    confirm: () => {
        console.log(&#39;点击了确认&#39;)
    },
    cancel: () => {
        console.log(&#39;点击了取消&#39;)
    }
})
Copy after login

Now the basic functions have been implemented, but someone wants to say that it is inconvenient to call like this. I want to call like this

open(msg).then(() => {
    console.log(&#39;点击了确认&#39;)
}).catch(() => {
     console.log(&#39;点击了取消&#39;)
})
Copy after login

How to implement it What about promise? The simplest way is to let the open method return a promise. How to enter the then method when clicking confirm or cancel? See the following writing method

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

If you want to encapsulate other separate methods, such as confirm, you can Extended based on open:

confirm(msg, option = {}) {
        if (typeof msg === &#39;object&#39;) {
                option = msg
        } else {
                option.msg = msg
        }
        return this.open({
                ...option,
                showCancelButton: true,
                type: &#39;confirm&#39;
        })
}
// 调用方式
this.$refs.stLayer.confirm(&#39;是否确认?&#39;).then().catch()
Copy after login

Such basic elastic layer components have been implemented. The following is the last stepGlobal useTo use the layer component written in the original vue project globally, it is usually injected into the page using the following method

import main from &#39;./main.vue&#39;

const LayerConstructor = vue.extend(main)

const initInstance = () => {
  instance = new LayerConstructor({
    el: document.createElement(&#39;div&#39;)
  })

  instance.callback = defaultCallback
  document.getElementById(&#39;app&#39;).appendChild(instance.$el)
}
Copy after login

It is directly pulled over and used, and the result is an error and prompt error: document is undefined, then I remembered that uni-app is very different from the ordinary vue project, which is introduced in its operating principle:

uni-app The logical layer and the view layer are separated. When running on the non-H5 end, it is divided into two parts: the logical layer and the view layer. The logic layer is responsible for executing business logic, that is, running js code, and the view layer is responsible for page rendering. Although developers write js and css in a vue page, they are actually split during compilation. The logic layer runs in an independent jscore. It does not depend on the local webview, so on the one hand it has no browser compatibility issues and can run es6 code on Android 4.4. On the other hand, it cannot run window, Browser-specific js APIs such as document, navigator, and localstorage.

So this method of global registration is no longer available. So how to implement it in uni-app? Looking through the official forum, I found an implementation of loadervue-inset-loader. The implementation principle is to obtain the sfc template content and insert custom content at the specified location (that is, components that require global ), the usage is as follows:

// 第一步
npm install vue-inset-loader --save-dev 
// 第二步 在vue.config.js(hbuilderx创建的项目没有的话新建一个)中注入loader
module.export = {
    chainWebpack: config => {
            // 超级全局组件
            config.module
                    .rule(&#39;vue&#39;)
                    .test(/\.vue$/)
                    .use()
                    .loader(path.resolve(__dirname, "./node_modules/vue-inset-loader"))
                    .end()
	} 
}
// 支持自定义pages.json文件路径  
// options: {  
//     pagesPath: path.resolve(__dirname,&#39;./src/pages.json&#39;)  
// } 
// 第三步 pages.json配置文件中添加insetLoader
"insetLoader": {  
    "config":{  
        "confirm": "<BaseConfirm ref=&#39;confirm&#39;></BaseConfirm>",  
        "abc": "<BaseAbc ref=&#39;BaseAbc&#39;></BaseAbc>"  
    },  
    // 全局配置  
    "label":["confirm"],  
    "rootEle":"div"  
}
Copy after login

Configuration instructions

  • config (default: {})
    Definition Key-value pair of label name and content

  • label(default: [])
    Labels that need to be introduced globally, after packaging This tag will be introduced in all pages

  • rootEle(default: "div")
    The tag type of the root element, default The value is div and supports regular rules. For example, it matches any label ".*"

    label and rootEle supports configuration in the style of a separate page and has a higher priority than the global one. After configuring

at this point, the component can be used globally. There is no need to write tags on each page to use it. You only need to call the API.

You can optimize it later based on usage. The level is limited, everyone’s advice is welcome.

Recommended: "uniapp tutorial"

The above is the detailed content of How to develop a global elastic layer component in uni-app (code example). For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:juejin.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template