偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

前端筆記:基于Dialog自定義實(shí)現(xiàn)類(lèi)似抽屜效果

開(kāi)發(fā) 項(xiàng)目管理
對(duì)于一些老項(xiàng)目無(wú)法升級(jí)ElementUI基礎(chǔ)框架且美觀(guān)和業(yè)務(wù)相對(duì)簡(jiǎn)單的情況下還是值得推薦嘗試的一種方案。如果是新項(xiàng)目推薦直接升級(jí)框架的方式最靠譜。官方提供的el-drawer才是最優(yōu)的選擇。

今天在維護(hù)vue2框架的一個(gè)業(yè)務(wù)系統(tǒng)遇到這樣一個(gè)問(wèn)題,有一個(gè)需求需要實(shí)現(xiàn)類(lèi)似于購(gòu)物車(chē)的效果,因?yàn)楸旧砜蚣苁褂玫氖荅lementUI框架,首先想到的就是使用官方提供的el-drawer。

圖片圖片

所以按照官方文檔準(zhǔn)備在現(xiàn)有系統(tǒng)寫(xiě)一個(gè)Demo,寫(xiě)完之后調(diào)試了半個(gè)小時(shí)。始終無(wú)法實(shí)現(xiàn)抽屜的效果。最后看了下elementui的版本是2.10.1,最后發(fā)現(xiàn)這個(gè)版本是不支持抽屜組件的。

圖片圖片

考慮到屬于老項(xiàng)目并且一直運(yùn)行比較穩(wěn)定,如果貿(mào)然升級(jí)elementui基礎(chǔ)框架的話(huà)風(fēng)險(xiǎn)還是非常大的。最后決定基于ElementUI的Dialog組件自定義的方式來(lái)實(shí)現(xiàn)抽屜的效果。下面給大家分享具體實(shí)現(xiàn)的過(guò)程,感興趣的前端朋友可以看一看!

二、代碼介紹

這部分相對(duì)比較簡(jiǎn)單,直接使用Dialog組件的基本結(jié)構(gòu),然后通過(guò)自定義模板實(shí)現(xiàn)類(lèi)似抽屜的標(biāo)題欄和內(nèi)容區(qū)域。

2.1 CSS部分

這部分是核心,需要定位對(duì)話(huà)框位置在頁(yè)面最右側(cè),并且實(shí)現(xiàn)類(lèi)似于抽屜從右向左滑動(dòng)的效果。

定位與尺寸

  • 使用position: fixed將Dialog固定到視口右側(cè)
  • 設(shè)置height: 100vh實(shí)現(xiàn)全高效果
  • 通過(guò)right: 0top: 0定位到右上角
  • 去除默認(rèn)的圓角(border-radius: 0)和邊距(margin: 0)

動(dòng)畫(huà)效果

頁(yè)面初始狀態(tài)使用transform: translateX(100%)將Dialog對(duì)話(huà)框隱藏在右側(cè)之外,需要打開(kāi)對(duì)話(huà)框的時(shí)候通過(guò)CSS transition實(shí)現(xiàn)平滑的滑入效果。

.drawer-dialog {  transform: translateX(100%);  transition: transform 0.3s ease-out;}.drawer-dialog.dialog-fade-enter-active {  transform: translateX(0);}

.drawer-dialog {
  transform: translateX(100%);
  transition: transform 0.3s ease-out;
}
.drawer-dialog.dialog-fade-enter-active {
  transform: translateX(0);
}

2.2 JS部分

主要是實(shí)現(xiàn)抽屜的展示、隱藏邏輯、狀態(tài)管理、計(jì)算抽屜的寬度功能。

2.3 完整的代碼示例

<!DOCTYPE html><html lang="zh-CN"><head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>右側(cè)滑出抽屜組件</title>    <link rel="stylesheet" >    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>    <script src="https://unpkg.com/element-ui/lib/index.js"></script>    <style>        * {            margin: 0;            padding: 0;            box-sizing: border-box;        }        body {            font-family: 'Helvetica Neue', Arial, sans-serif;            background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);            min-height: 100vh;            display: flex;            flex-direction: column;            align-items: center;            padding: 40px 20px;            color: #2c3e50;        }        .container {            max-width: 800px;            width: 100%;            text-align: center;        }        h1 {            margin-bottom: 20px;            font-weight: 500;        }        .description {            margin-bottom: 30px;            color: #5e6d82;            line-height: 1.6;        }        .control-panel {            background: white;            border-radius: 8px;            padding: 25px;            margin-bottom: 30px;            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);        }        .button-group {            display: flex;            justify-content: center;            gap: 15px;            margin-bottom: 20px;            flex-wrap: wrap;        }        .demo-content {            background: white;            border-radius: 8px;            padding: 30px;            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);            margin-bottom: 30px;        }        .demo-content p {            margin-bottom: 15px;            color: #5e6d82;        }        .status-info {            margin-top: 20px;            padding: 12px;            background: #f0f9ff;            border-radius: 4px;            border-left: 4px solid #409EFF;        }        /* 抽屜組件樣式 */        .slide-drawer-mask {            position: fixed;            top: 0;            left: 0;            width: 100%;            height: 100%;            background-color: rgba(0, 0, 0, 0.5);            z-index: 9998;        }        .slide-drawer {            position: fixed;            top: 0;            right: 0;            height: 100%;            background: white;            box-shadow: -2px 0 12px rgba(0, 0, 0, 0.15);            display: flex;            flex-direction: column;            z-index: 9999;        }        .slide-drawer-header {            display: flex;            justify-content: space-between;            align-items: center;            padding: 16px 20px;            border-bottom: 1px solid #e6e9ed;            background-color: #f5f7fa;        }        .slide-drawer-title {            font-size: 16px;            font-weight: 600;        }        .slide-drawer-close {            cursor: pointer;            color: #909399;            font-size: 16px;            padding: 5px;        }        .slide-drawer-close:hover {            color: #409EFF;        }        .slide-drawer-body {            padding: 20px;            flex: 1;            overflow-y: auto;        }        /* 過(guò)渡動(dòng)畫(huà) */        .fade-enter-active, .fade-leave-active {            transition: opacity 0.3s;        }        .fade-enter, .fade-leave-to {            opacity: 0;        }        .slide-right-enter-active, .slide-right-leave-active {            transition: transform 0.3s ease-out;        }        .slide-right-enter, .slide-right-leave-to {            transform: translateX(100%);        }        /* 響應(yīng)式設(shè)計(jì) */        @media (max-width: 768px) {            .button-group {                flex-direction: column;                align-items: center;            }            .slide-drawer {                width: 85% !important;            }        }    </style></head><body>    <div id="app">        <div class="container">            <h1>右側(cè)滑出抽屜組件</h1>                    <div class="control-panel">                <div class="button-group">                    <el-button type="primary" @click="openDrawer">打開(kāi)抽屜</el-button>                    <el-button type="success" @click="openDrawer(0.25)">25%寬度</el-button>                    <el-button type="warning" @click="openDrawer(0.5)">50%寬度</el-button>                    <el-button type="danger" @click="openDrawer(0.75)">75%寬度</el-button>                </div>            </div>            <div class="demo-content">                <p>這是一個(gè)使用封裝好的右側(cè)抽屜組件示例。</p>                <p>組件采用簡(jiǎn)潔的設(shè)計(jì)風(fēng)格,支持自定義寬度和內(nèi)容。</p>                <el-button type="text" @click="openDrawer">立即嘗試打開(kāi)抽屜</el-button>                <div class="status-info" v-if="statusMessage">                    {{ statusMessage }}                </div>            </div>        </div>        <!-- 抽屜組件 -->        <slide-drawer            :visible="drawerVisible"            :width-ratio="drawerRatio"            title="右側(cè)抽屜"            @close="handleClose">            <div class="drawer-content">                <p>這是從右側(cè)滑出的抽屜內(nèi)容</p>                <p>當(dāng)前寬度: {{ Math.round(drawerRatio * 100) }}%</p>                <p>您可以在這里放置任何需要的內(nèi)容</p>                <el-divider></el-divider>                <p>支持各種HTML元素和組件</p>            </div>        </slide-drawer>    </div>    <script>        // 定義抽屜組件        Vue.component('slide-drawer', {            props: {                visible: Boolean,                title: {                    type: String,                    default: '抽屜默認(rèn)標(biāo)題'                },                widthRatio: {                    type: Number,                    default: 0.3,                    validator: value => value > 0 && value <= 1                },                customStyle: {                    type: Object,                    default: function() {                        return {};                    }                }            },            computed: {                drawerStyle() {                    return {                        width: `${this.widthRatio * 100}%`,                        ...this.customStyle                    };                }            },            methods: {                close() {                    this.$emit('close');                },                handleMaskClick() {                    this.close();                }            },            template: `                <div v-if="visible">                    <transition name="fade">                        <div class="slide-drawer-mask" @click="handleMaskClick"></div>                    </transition>                    <transition name="slide-right">                        <div class="slide-drawer" :style="drawerStyle">                            <div class="slide-drawer-header">                                <span class="slide-drawer-title">{{ title }}</span>                                <span class="slide-drawer-close" @click="close">                                    <i class="el-icon-close"></i>                                </span>                            </div>                            <div class="slide-drawer-body">                                <slot></slot>                            </div>                        </div>                    </transition>                </div>            `        });        new Vue({            el: '#app',            data() {                return {                    drawerVisible: false,                    drawerRatio: 0.3,                    statusMessage: ''                };            },            methods: {                openDrawer(ratio) {                    if (ratio) {                        this.drawerRatio = ratio;                    }                    this.drawerVisible = true;                },                handleClose() {                    this.drawerVisible = false;                    this.statusMessage = '抽屜已關(guān)閉';                    setTimeout(() => {                        this.statusMessage = '';                    }, 2000);                }            }        });    </script></body></html>

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>右側(cè)滑出抽屜組件</title>
    <link rel="stylesheet" >
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            font-family: 'Helvetica Neue', Arial, sans-serif;
            background: linear-gradient(135deg, 
#f5f7fa
 0%, 
#c3cfe2
 100%);
            min-height: 100vh;
            display: flex;
            flex-direction: column;
            align-items: center;
            padding: 40px 20px;
            color: 
#2c3e50
;
        }
        .container {
            max-width: 800px;
            width: 100%;
            text-align: center;
        }
        h1 {
            margin-bottom: 20px;
            font-weight: 500;
        }
        .description {
            margin-bottom: 30px;
            color: 
#5e6d82
;
            line-height: 1.6;
        }
        .control-panel {
            background: white;
            border-radius: 8px;
            padding: 25px;
            margin-bottom: 30px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
        }
        .button-group {
            display: flex;
            justify-content: center;
            gap: 15px;
            margin-bottom: 20px;
            flex-wrap: wrap;
        }
        .demo-content {
            background: white;
            border-radius: 8px;
            padding: 30px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
            margin-bottom: 30px;
        }
        .demo-content p {
            margin-bottom: 15px;
            color: 
#5e6d82
;
        }
        .status-info {
            margin-top: 20px;
            padding: 12px;
            background: 
#f0f9ff
;
            border-radius: 4px;
            border-left: 4px solid 
#409EFF
;
        }
        /* 抽屜組件樣式 */
        .slide-drawer-mask {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.5);
            z-index: 9998;
        }
        .slide-drawer {
            position: fixed;
            top: 0;
            right: 0;
            height: 100%;
            background: white;
            box-shadow: -2px 0 12px rgba(0, 0, 0, 0.15);
            display: flex;
            flex-direction: column;
            z-index: 9999;
        }
        .slide-drawer-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 16px 20px;
            border-bottom: 1px solid 
#e6e9ed
;
            background-color: 
#f5f7fa
;
        }
        .slide-drawer-title {
            font-size: 16px;
            font-weight: 600;
        }
        .slide-drawer-close {
            cursor: pointer;
            color: 
#909399
;
            font-size: 16px;
            padding: 5px;
        }
        .slide-drawer-close:hover {
            color: 
#409EFF
;
        }
        .slide-drawer-body {
            padding: 20px;
            flex: 1;
            overflow-y: auto;
        }
        /* 過(guò)渡動(dòng)畫(huà) */
        .fade-enter-active, .fade-leave-active {
            transition: opacity 0.3s;
        }
        .fade-enter, .fade-leave-to {
            opacity: 0;
        }
        .slide-right-enter-active, .slide-right-leave-active {
            transition: transform 0.3s ease-out;
        }
        .slide-right-enter, .slide-right-leave-to {
            transform: translateX(100%);
        }
        /* 響應(yīng)式設(shè)計(jì) */
        @media (max-width: 768px) {
            .button-group {
                flex-direction: column;
                align-items: center;
            }
            .slide-drawer {
                width: 85% !important;
            }
        }
    </style>
</head>
<body>
    <div id="app">
        <div class="container">
            <h1>右側(cè)滑出抽屜組件</h1>        
            <div class="control-panel">
                <div class="button-group">
                    <el-button type="primary" @click="openDrawer">打開(kāi)抽屜</el-button>
                    <el-button type="success" @click="openDrawer(0.25)">25%寬度</el-button>
                    <el-button type="warning" @click="openDrawer(0.5)">50%寬度</el-button>
                    <el-button type="danger" @click="openDrawer(0.75)">75%寬度</el-button>
                </div>
            </div>
            <div class="demo-content">
                <p>這是一個(gè)使用封裝好的右側(cè)抽屜組件示例。</p>
                <p>組件采用簡(jiǎn)潔的設(shè)計(jì)風(fēng)格,支持自定義寬度和內(nèi)容。</p>
                <el-button type="text" @click="openDrawer">立即嘗試打開(kāi)抽屜</el-button>
                <div class="status-info" v-if="statusMessage">
                    {{ statusMessage }}
                </div>
            </div>
        </div>
        <!-- 抽屜組件 -->
        <slide-drawer
            :visible="drawerVisible"
            :width-ratio="drawerRatio"
            title="右側(cè)抽屜"
            @close="handleClose">
            <div class="drawer-content">
                <p>這是從右側(cè)滑出的抽屜內(nèi)容</p>
                <p>當(dāng)前寬度: {{ Math.round(drawerRatio * 100) }}%</p>
                <p>您可以在這里放置任何需要的內(nèi)容</p>
                <el-divider></el-divider>
                <p>支持各種HTML元素和組件</p>
            </div>
        </slide-drawer>
    </div>
    <script>
        // 定義抽屜組件
        Vue.component('slide-drawer', {
            props: {
                visible: Boolean,
                title: {
                    type: String,
                    default: '抽屜默認(rèn)標(biāo)題'
                },
                widthRatio: {
                    type: Number,
                    default: 0.3,
                    validator: value => value > 0 && value <= 1
                },
                customStyle: {
                    type: Object,
                    default: function() {
                        return {};
                    }
                }
            },
            computed: {
                drawerStyle() {
                    return {
                        width: `${this.widthRatio * 100}%`,
                        ...this.customStyle
                    };
                }
            },
            methods: {
                close() {
                    this.$emit('close');
                },
                handleMaskClick() {
                    this.close();
                }
            },
            template: `
                <div v-if="visible">
                    <transition name="fade">
                        <div class="slide-drawer-mask" @click="handleMaskClick"></div>
                    </transition>
                    <transition name="slide-right">
                        <div class="slide-drawer" :style="drawerStyle">
                            <div class="slide-drawer-header">
                                <span class="slide-drawer-title">{{ title }}</span>
                                <span class="slide-drawer-close" @click="close">
                                    <i class="el-icon-close"></i>
                                </span>
                            </div>
                            <div class="slide-drawer-body">
                                <slot></slot>
                            </div>
                        </div>
                    </transition>
                </div>
            `
        });
        new Vue({
            el: '
#app
',
            data() {
                return {
                    drawerVisible: false,
                    drawerRatio: 0.3,
                    statusMessage: ''
                };
            },
            methods: {
                openDrawer(ratio) {
                    if (ratio) {
                        this.drawerRatio = ratio;
                    }
                    this.drawerVisible = true;
                },
                handleClose() {
                    this.drawerVisible = false;
                    this.statusMessage = '抽屜已關(guān)閉';
                    setTimeout(() => {
                        this.statusMessage = '';
                    }, 2000);
                }
            }
        });
    </script>
</body>
</html>

2.4 運(yùn)行效果

為了方面可以直接運(yùn)行。這里直接采用了CDN方式引入js和css。復(fù)制代碼后可以直接保存為html文件然后直接瀏覽器打開(kāi)。預(yù)覽效果如下:

圖片圖片

首先測(cè)試點(diǎn)擊25%寬度;

圖片圖片

然后測(cè)試點(diǎn)擊75%寬度。

圖片圖片

三、總結(jié)

以上功能是一個(gè)相對(duì)比較簡(jiǎn)單的基于Dialog自定義實(shí)現(xiàn)類(lèi)似抽屜效果的實(shí)用案例。對(duì)于一些老項(xiàng)目無(wú)法升級(jí)ElementUI基礎(chǔ)框架且美觀(guān)和業(yè)務(wù)相對(duì)簡(jiǎn)單的情況下還是值得推薦嘗試的一種方案。如果是新項(xiàng)目推薦直接升級(jí)框架的方式最靠譜。官方提供的el-drawer才是最優(yōu)的選擇。

責(zé)任編輯:武曉燕 來(lái)源: 小明互聯(lián)網(wǎng)技術(shù)分享社區(qū)
相關(guān)推薦

2021-12-21 15:22:22

鴻蒙HarmonyOS應(yīng)用

2022-05-18 07:44:13

自定義菜單前端

2013-01-06 10:43:54

Android開(kāi)發(fā)View特效

2024-05-30 08:23:37

ViewPager滑動(dòng)效果接口

2022-09-21 14:42:03

JSProps屬性

2022-09-09 14:47:50

CircleArkUI

2009-09-07 22:00:15

LINQ自定義

2021-09-14 15:13:18

鴻蒙HarmonyOS應(yīng)用

2013-03-28 10:58:30

自定義Android界android

2020-09-18 10:12:24

KotlinTCP網(wǎng)絡(luò)協(xié)議

2015-02-12 15:33:43

微信SDK

2013-01-09 17:22:38

Android開(kāi)發(fā)Camera

2023-01-03 07:40:27

自定義滑塊組件

2022-04-01 15:59:22

SQLPostgreSQL審計(jì)

2009-06-17 16:00:03

Hibernate自定

2023-10-24 13:48:50

自定義注解舉值驗(yàn)證

2015-07-29 10:31:16

Java緩存算法

2009-09-03 13:34:03

.NET自定義控件

2022-03-01 16:09:06

OpenHarmon鴻蒙單選組件

2022-12-07 08:56:27

SpringMVC核心組件
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)