欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用Vue封裝一個自定義的右鍵菜單組件

 更新時間:2024年01月23日 10:26:57   作者:JYeontu  
通過自定義右鍵菜單欄,用戶可以根據(jù)自己的需求添加、調(diào)整和刪除菜單選項,所以本文就來為大家介紹一下如何使用使用Vue封裝一個自定義的右鍵菜單組件吧

說在前面

網(wǎng)頁的功能和用途可能各不相同,在傳統(tǒng)右鍵菜單欄中無法滿足每個用戶的個性化需求。通過自定義右鍵菜單欄,用戶可以根據(jù)自己的需求添加、調(diào)整和刪除菜單選項,以實現(xiàn)個性化定制。通過自定義右鍵菜單欄,可以為用戶提供快速訪問常用功能和操作的便捷方式,從而提高用戶體驗。

效果展示

實現(xiàn)原理

1、oncontextmenu事件了解一下

oncontextmenu 事件在元素中用戶右擊鼠標(biāo)時觸發(fā)并打開上下文菜單。

oncontextmenu是一個DOM事件,它在用戶右鍵點擊時觸發(fā)??梢酝ㄟ^在HTML元素上添加oncontextmenu屬性來指定右鍵菜單的處理函數(shù)。

例如,在一個按鈕元素上添加oncontextmenu屬性:

<button oncontextmenu="showContextMenu(event)">右鍵點擊我</button>

在這個示例中,當(dāng)用戶右鍵點擊按鈕時,會調(diào)用showContextMenu函數(shù),并將事件對象作為參數(shù)傳遞給該函數(shù)。

在JavaScript代碼中,可以定義showContextMenu函數(shù)來處理右鍵菜單的顯示和操作:

function showContextMenu(event) {
  event.preventDefault(); // 阻止默認(rèn)的右鍵菜單彈出
  // 顯示自定義右鍵菜單
  // ...
}

在showContextMenu函數(shù)中,通過調(diào)用event.preventDefault()方法阻止瀏覽器默認(rèn)的右鍵菜單彈出。然后,可以根據(jù)需要執(zhí)行自定義的邏輯,例如顯示自定義的右鍵菜單。

2、在指定容器元素自定義右鍵菜單

首先,使用getElementById方法獲取綁定右鍵菜單的DOM元素和右鍵菜單的容器元素。如果獲取失敗,則直接返回。

const dom = document.getElementById(this.domId);
if (!dom) return;

接著,給綁定右鍵菜單的DOM元素添加oncontextmenu事件處理函數(shù)。當(dāng)用戶觸發(fā)右鍵點擊事件時,首先調(diào)用hideAllMenu方法隱藏所有的右鍵菜單,然后通過event.preventDefault方法禁止默認(rèn)行為,防止瀏覽器彈出默認(rèn)的右鍵菜單。接下來,計算出鼠標(biāo)指針相對于文檔頂部和左側(cè)的位置,并設(shè)置右鍵菜單的位置和顯示狀態(tài)。

const that = this;
dom.oncontextmenu = function (e) {
    that.hideAllMenu(that.uid);
    // 自定義body元素的鼠標(biāo)事件處理函數(shù)
    e = e || window.event;
    e.preventDefault();
    let scrollTop =
        document.documentElement.scrollTop ||
        document.body.scrollTop; // 獲取垂直滾動條位置
    let scrollLeft =
        document.documentElement.scrollLeft ||
        document.body.scrollLeft; // 獲取水平滾動條位置
    menu.style.display = "block";
    menu.style.left = e.clientX + scrollLeft + "px";
    menu.style.top = e.clientY + scrollTop + "px";
};

最后,給document對象添加onclick事件處理函數(shù)。當(dāng)用戶在其他位置點擊鼠標(biāo)時,調(diào)用hideAllMenu方法隱藏所有的右鍵菜單。

document.onclick = function () {
    that.hideAllMenu();
};
hideAllMenu(id) {
    const jMenu = document.getElementsByClassName("j-mouse-menu");
    for (let i = 0; i < jMenu.length; i++) {
        if (jMenu[i].id != id) jMenu[i].style.display = "none";
    }
},

3、封裝成一個組件

(1)template菜單模板

<div :id="uid" class="j-mouse-menu">
    <slot name="header"></slot>
    <ul>
        <li
            v-for="menuItem in menu"
            :key="menuItem.id"
            @click="menuClick(menuItem)"
        >
            {{ menuItem.label }}
        </li>
    </ul>
    <slot name="body"></slot>
    <slot name="footer"></slot>
</div>

使用:id="uid"綁定了組件的id屬性,該屬性值由組件實例的uid屬性提供。這樣可以確保每個組件實例都有唯一的id。

然后,給組件添加了j-mouse-menu類,用于設(shè)置組件的樣式。

在組件的內(nèi)容區(qū)域中,使用了Vue的插槽機制。

  • <slot name="header"></slot>定義了一個名為"header"的插槽,用于放置菜單欄的頭部內(nèi)容。
  • <ul>標(biāo)簽下使用了v-for指令遍歷menu數(shù)組,生成菜單項。
  • 菜單項使用<li>標(biāo)簽表示,并通過:key綁定了唯一的menuItem.id作為key值。
  • 通過@click綁定了menuClick方法,該方法會在點擊菜單項時被調(diào)用。
  • 菜單項的顯示文本使用插值語法{{ menuItem.label }}來動態(tài)顯示。

接下來,又定義了兩個插槽:

  • <slot name="body"></slot>用于放置菜單欄的主體內(nèi)容。
  • <slot name="footer"></slot>用于放置菜單欄的底部內(nèi)容。

(2)props入?yún)?/strong>

props: {
    domId: {
        type: String,
        default: "",
    },
    menu: {
        type: Array,
        default: () => {
            return [];
        },
    },
},

domId表示需要綁定右鍵菜單的DOM元素容器的id,menu表示右鍵菜單的選項列表,menu數(shù)據(jù)格式如下:

[
    {
        id: "1",
        label: "菜單1"
    },
    {
        id: "2",
        label: "菜單2",
        click: this.test
    },
    {
        id: "3",
        label: "菜單3"
    },
    {
        id: "4",
        label: "菜單4"
    },
    {
        id: "5",
        label: "菜單5"
    }
]

(3)菜單點擊回調(diào)

menuClick(item) {
    if (item.click) {
        item.click(item);
        return;
    }
    this.$emit("menuClick", item);
},

首先判斷item對象是否存在click屬性。如果存在,則執(zhí)行item.click(item),并將item作為參數(shù)傳遞給click函數(shù)。然后,返回結(jié)束方法的執(zhí)行。

如果item對象不存在click屬性,即沒有自定義的點擊處理函數(shù),那么就通過this.$emit("menuClick", item)語法觸發(fā)一個名為"menuClick"的自定義事件,并將item作為參數(shù)傳遞給父組件。

(4)完整組件代碼

<template>
    <div>
        <div :id="uid" class="j-mouse-menu">
            <slot name="header"></slot>
            <ul>
                <li
                    v-for="menuItem in menu"
                    :key="menuItem.id"
                    @click="menuClick(menuItem)"
                >
                    {{ menuItem.label }}
                </li>
            </ul>
            <slot name="body"></slot>
            <slot name="footer"></slot>
        </div>
    </div>
</template>

<script>
import { getUId } from "../../../utils/strTool";
export default {
    name: "JMouseMenu",
    props: {
        domId: {
            type: String,
            default: "",
        },
        menu: {
            type: Array,
            default: () => {
                return [];
            },
        },
    },
    data() {
        return {
            uid: "",
        };
    },
    created() {
        this.setUid();
    },
    mounted() {
        this.init();
    },
    methods: {
        setUid() {
            this.uid = "j-mouse-menu-" + getUId();
        },
        init() {
            // 自定義鼠標(biāo)右鍵菜單欄
            const dom = document.getElementById(this.domId);
            if (!dom) return;
            const menu = document.getElementById(this.uid);
            const that = this;
            dom.oncontextmenu = function (e) {
                that.hideAllMenu(that.uid);
                // 自定義body元素的鼠標(biāo)事件處理函數(shù)
                e = e || window.event;
                e.preventDefault();
                let scrollTop =
                    document.documentElement.scrollTop ||
                    document.body.scrollTop; // 獲取垂直滾動條位置
                let scrollLeft =
                    document.documentElement.scrollLeft ||
                    document.body.scrollLeft; // 獲取水平滾動條位置
                menu.style.display = "block";
                menu.style.left = e.clientX + scrollLeft + "px";
                menu.style.top = e.clientY + scrollTop + "px";
            };
            // 鼠標(biāo)點擊其他位置時隱藏菜單
            document.onclick = function () {
                that.hideAllMenu();
            };
        },
        hideAllMenu(id) {
            const jMenu = document.getElementsByClassName("j-mouse-menu");
            for (let i = 0; i < jMenu.length; i++) {
                if (jMenu[i].id != id) jMenu[i].style.display = "none";
            }
        },
        menuClick(item) {
            if (item.click) {
                item.click(item);
                return;
            }
            this.$emit("menuClick", item);
        },
    },
};
</script>

<style lang="less" scoped>
.j-mouse-menu {
    display: none;
    position: absolute;
    min-width: 8em;
    max-width: 15em;
    border: 1px solid #ccc;
    background: #eee;
    ul {
        margin: 5px 0;
        padding: 0;
    }
    li {
        height: 30px;
        line-height: 30px;
        color: #21232e;
        font-size: 12px;
        text-align: center;
        cursor: default;
        padding: 0;
        margin: 0;
        list-style-type: none;
        border-bottom: 1px dashed #cecece;
        &:hover {
            background-color: #cccccc;
        }
    }
}
</style>

(5)組件使用

<j-mouse-menu
    :domId="'j-mouse-menu-view-content1'"
    :menu="myMenu"
    @menuClick="menuClick"
>
    <template v-slot:header>
        <div class="menu-slot-header">??JYeontu</div>
    </template>
    <template v-slot:footer>
        <div class="menu-slot">
            ????
        </div>
    </template>
</j-mouse-menu>

通過插槽自定義右鍵菜單的頭部和底部內(nèi)容,菜單列表通過menu參數(shù)傳入子組件,并綁定菜單點擊事件menuClick。

data(){
    return {
        myMenu: [
            {
                id: "1",
                label: "菜單1"
            },
            {
                id: "2",
                label: "菜單2",
                click: this.test
            },
            {
                id: "3",
                label: "菜單3"
            },
            {
                id: "4",
                label: "菜單4"
            },
            {
                id: "5",
                label: "菜單5"
            }
        ]
    }
},
methods:{
    menuClick(menuItem) {
        alert("點擊了:" + menuItem.label);
    },
    test(menuItem) {
        alert("test-" + menuItem.id);
    },
    alert(label) {
        alert("點擊了:" + label);
    }
}

組件庫

組件文檔

目前該組件也已經(jīng)收錄到我的組件庫,組件文檔地址如下:http://jyeontu.xyz/jvuewheel/#/JMouseMenu

組件內(nèi)容

組件庫中還有許多好玩有趣的組件,如:

  • 懸浮按鈕
  • 評論組件
  • 詞云
  • 瀑布流照片容器
  • 視頻動態(tài)封面
  • 3D輪播圖
  • web桌寵
  • 貢獻(xiàn)度面板
  • 拖拽上傳
  • 自動補全輸入框
  • 圖片滑塊驗證

等等……

組件庫源碼

組件庫已開源到gitee,有興趣的也可以到這里看看:https://gitee.com/zheng_yongtao/jyeontu-component-warehouse

以上就是使用Vue封裝一個自定義的右鍵菜單組件的詳細(xì)內(nèi)容,更多關(guān)于Vue自定義右鍵菜單組件的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Vue中如何運用TS語法

    Vue中如何運用TS語法

    本文主要介紹了Vue中如何運用TS語法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • 基于Vue實現(xiàn)timepicker

    基于Vue實現(xiàn)timepicker

    這篇文章主要為大家詳細(xì)介紹了基于Vue實現(xiàn)timepicker效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • vue數(shù)據(jù)變化但頁面刷新問題

    vue數(shù)據(jù)變化但頁面刷新問題

    這篇文章主要介紹了vue數(shù)據(jù)變化但頁面刷新問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • vue?serve及其與vue-cli-service?serve之間的關(guān)系解讀

    vue?serve及其與vue-cli-service?serve之間的關(guān)系解讀

    這篇文章主要介紹了vue?serve及其與vue-cli-service?serve之間的關(guān)系,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • vue之組件內(nèi)監(jiān)控$store中定義變量的變化詳解

    vue之組件內(nèi)監(jiān)控$store中定義變量的變化詳解

    今天小編就為大家分享一篇vue之組件內(nèi)監(jiān)控$store中定義變量的變化詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • el-radio-group中的area-hidden報錯的問題解決

    el-radio-group中的area-hidden報錯的問題解決

    本文主要介紹了el-radio-group中的area-hidden報錯的問題解決,下面就來介紹幾種解決方法,具有一定的參考價值,感興趣的可以了解一下
    2025-04-04
  • vue中同時監(jiān)聽多個參數(shù)的實現(xiàn)

    vue中同時監(jiān)聽多個參數(shù)的實現(xiàn)

    這篇文章主要介紹了vue中同時監(jiān)聽多個參數(shù)的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • Vue進(jìn)度條progressbar組件功能

    Vue進(jìn)度條progressbar組件功能

    progressbar組件在一個可以直接運行的npm包,通過Yeoman進(jìn)行構(gòu)建,再通過Gulp+Webpack構(gòu)建工具。這篇文章給大家介紹了Vue進(jìn)度條progressbar組件
    2018-04-04
  • vue實現(xiàn)放大縮小拖拽功能

    vue實現(xiàn)放大縮小拖拽功能

    這篇文章主要為大家詳細(xì)介紹了vue實現(xiàn)放大縮小拖拽功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • vue內(nèi)置指令詳解

    vue內(nèi)置指令詳解

    指令是Vue模板中最常用的一項功能,它帶有前綴v-,主要職責(zé)是當(dāng)其表達(dá)式的值改變時,相應(yīng)的將某些行為應(yīng)用在 DOM 上。這篇文章主要介紹了vue內(nèi)置指令詳解,需要的朋友可以參考下
    2018-04-04

最新評論