最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

說(shuō)在前面

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

效果展示

實(shí)現(xiàn)原理

1、oncontextmenu事件了解一下

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

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

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

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

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

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

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

在showContextMenu函數(shù)中,通過(guò)調(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ǎn)擊事件時(shí),首先調(diào)用hideAllMenu方法隱藏所有的右鍵菜單,然后通過(guò)event.preventDefault方法禁止默認(rèn)行為,防止瀏覽器彈出默認(rèn)的右鍵菜單。接下來(lái),計(jì)算出鼠標(biāo)指針相對(duì)于文檔頂部和左側(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; // 獲取垂直滾動(dòng)條位置
    let scrollLeft =
        document.documentElement.scrollLeft ||
        document.body.scrollLeft; // 獲取水平滾動(dòng)條位置
    menu.style.display = "block";
    menu.style.left = e.clientX + scrollLeft + "px";
    menu.style.top = e.clientY + scrollTop + "px";
};

最后,給document對(duì)象添加onclick事件處理函數(shù)。當(dāng)用戶在其他位置點(diǎn)擊鼠標(biāo)時(shí),調(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、封裝成一個(gè)組件

(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屬性,該屬性值由組件實(shí)例的uid屬性提供。這樣可以確保每個(gè)組件實(shí)例都有唯一的id。

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

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

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

接下來(lái),又定義了兩個(gè)插槽:

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

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

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

domId表示需要綁定右鍵菜單的DOM元素容器的id,menu表示右鍵菜單的選項(xiàng)列表,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ǎn)擊回調(diào)

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

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

如果item對(duì)象不存在click屬性,即沒(méi)有自定義的點(diǎn)擊處理函數(shù),那么就通過(guò)this.$emit("menuClick", item)語(yǔ)法觸發(fā)一個(gè)名為"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; // 獲取垂直滾動(dòng)條位置
                let scrollLeft =
                    document.documentElement.scrollLeft ||
                    document.body.scrollLeft; // 獲取水平滾動(dòng)條位置
                menu.style.display = "block";
                menu.style.left = e.clientX + scrollLeft + "px";
                menu.style.top = e.clientY + scrollTop + "px";
            };
            // 鼠標(biāo)點(diǎn)擊其他位置時(shí)隱藏菜單
            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>

通過(guò)插槽自定義右鍵菜單的頭部和底部?jī)?nèi)容,菜單列表通過(guò)menu參數(shù)傳入子組件,并綁定菜單點(diǎn)擊事件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("點(diǎn)擊了:" + menuItem.label);
    },
    test(menuItem) {
        alert("test-" + menuItem.id);
    },
    alert(label) {
        alert("點(diǎn)擊了:" + label);
    }
}

組件庫(kù)

組件文檔

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

組件內(nèi)容

組件庫(kù)中還有許多好玩有趣的組件,如:

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

等等……

組件庫(kù)源碼

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

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

相關(guān)文章

最新評(píng)論

四川省| 潜江市| 柏乡县| 青州市| 会同县| 焦作市| 仙游县| 吉安市| 井冈山市| 全州县| 曲阜市| 伊川县| 蕉岭县| 隆回县| 明光市| 商南县| 犍为县| 洪泽县| 长阳| 会理县| 项城市| 微博| 翁源县| 轮台县| 汝城县| 南投市| 汶川县| 家居| 兴化市| 安龙县| 象山县| 韶关市| 易门县| 屯昌县| 吉木萨尔县| 鸡泽县| 湛江市| 千阳县| 景东| 崇义县| 枣庄市|