Vue實(shí)現(xiàn)自定義右擊刪除菜單的示例
一、定義和使用
oncontextmenu 事件在元素中用戶(hù)右擊鼠標(biāo)時(shí)觸發(fā)并打開(kāi)上下文菜單。
注意:所有瀏覽器都支持 oncontextmenu 事件, contextmenu 元素只有 Firefox 瀏覽器支持。
二、語(yǔ)法
HTML 中:
<element oncontextmenu="myScript">
JavaScript 中:
object.oncontextmenu=function(){myScript};JavaScript 中, 使用 addEventListener() 方法:
object.addEventListener("contextmenu", myScript);jQuery中,使用on監(jiān)聽(tīng)事件
$(document).on('contextmenu', myScript);注意: Internet Explorer 8 及更早 IE 瀏覽器版本不支持 addEventListener() 。
三、使用細(xì)節(jié)
是否支持冒泡: | Yes |
是否可以取消: | Yes |
事件類(lèi)型: | MouseEvent |
支持的 HTML 標(biāo)簽: | 所有 HTML 元素 |
四、案例
這通過(guò)一個(gè)小案例,在考勤統(tǒng)計(jì)列表中,每行中對(duì)應(yīng)某員工這月周期內(nèi)的每天考勤數(shù)據(jù);如果某條記錄需要?jiǎng)h除,這里通過(guò)在記錄上直接右擊出現(xiàn)刪除菜單,操作起來(lái)則更為方便。如下圖:

4.1 自定義右擊刪除菜單步驟
通過(guò)DOM對(duì)象監(jiān)聽(tīng)鼠標(biāo)點(diǎn)擊事件
觸發(fā)鼠標(biāo)點(diǎn)擊事件,獲取鼠標(biāo)當(dāng)前瀏覽器位置
根據(jù)當(dāng)前位置重新調(diào)整自定義contextmenu的位置
顯示自定義contextmenu
4.2 技術(shù)點(diǎn)
這里使用Vue技術(shù)框架來(lái)做這個(gè)案例,統(tǒng)計(jì)列表使用是element-ui中的table組件,事件監(jiān)聽(tīng)和數(shù)據(jù)獲取通過(guò)jquery實(shí)現(xiàn),在開(kāi)發(fā)前請(qǐng)將其通過(guò)npm進(jìn)行安裝。
//安裝element-ui npm i element-ui -S
//安裝jquery npm i jquery -S
4.3 html代碼
這里通過(guò)列數(shù)據(jù)中isDate判斷該列是否渲染為對(duì)應(yīng)日期列,渲染日期相對(duì)應(yīng)的考勤記錄時(shí),需要追加data-prop和data-id進(jìn)行數(shù)據(jù)傳遞,后續(xù)執(zhí)行刪除操作時(shí)會(huì)使用到。
<template>
<div class="list-wrap">
<el-table
stripe
:data="tableData"
class="list-table"
style="width: 100%">
<el-table-column type="selection" width="55" fixed="left"></el-table-column>
<template v-for="(item, index) in tableColumn">
<el-table-column :prop="item.prop" :label="item.name" :key="index" :width="item.width" v-if="item.isDate">
<template slot-scope="scope">
<span class="date-cell" v-html="scope.row[item.prop]"
:data-prop="item.prop"
:data-id="scope.row['id_'+item.prop]"></span>
</template>
</el-table-column>
<el-table-column :prop="item.prop" :label="item.name" :key="index" :width="item.width" v-else fixed="left"></el-table-column>
</template>
</el-table>
</div>
</template>
<style lang="scss">
@import './index.scss';
</style>4.4 CSS樣式
.date-cell類(lèi)選擇器對(duì)考勤記錄數(shù)據(jù)進(jìn)行樣式修改,更改鼠標(biāo)為小手圖標(biāo),并禁止選擇文本內(nèi)容,為避免后期右擊時(shí)會(huì)誤操作選中內(nèi)容。
.menu-box類(lèi)選擇器為右擊菜單增加基礎(chǔ)樣式。
.date-cell{ cursor: pointer;
-moz-user-select:none; /*火狐*/
-webkit-user-select:none; /*webkit瀏覽器*/
-ms-user-select:none; /*IE10*/
-khtml-user-select:none; /*早期瀏覽器*/
user-select:none;
}
.menu-box{
position: absolute;
ul.list{
background-color: #fff;
border: 1px solid #ccc;
li{
border-top: 1px solid #ccc;
padding: 6px 15px;
font-size: 14px;
line-height: 1.5;
color: #666;
list-style: none;
cursor: pointer;
&:first-child{
border-top: 0;
}
}
}
}4.5 基礎(chǔ)數(shù)據(jù)
變量tableData用于存儲(chǔ)員工考勤數(shù)據(jù),變量tableColumn用于存儲(chǔ)表格列頭部數(shù)據(jù)定義,在獲取考勤記錄后,動(dòng)態(tài)追加日期列到變量tableColumn中。
<script>
export default {
data(){
return {
tableData: [],
tableColumn: [
{prop: "name", name: "姓名", width: "80px"},
{prop: "workday", name: "實(shí)際到崗/天", width: "100px"},
]
}
},
created() {
},
methods: {
}
}
</script>此時(shí)頁(yè)面樣式如下圖:

4.6 模擬數(shù)據(jù)
這里在目錄位置新建demo.json文件,將以下數(shù)據(jù)拷入即可。
[
{"id":1482,"name":"張三","record":["08:30","18:00"],"recorddate":"2023-01-01"},
{"id":1481,"name":"張三","record":["08:30","18:00"],"recorddate":"2023-01-02"},
{"id":1480,"name":"張三","record":["08:30","18:00"],"recorddate":"2023-01-03"},
{"id":1479,"name":"張三","record":["08:30","18:00"],"recorddate":"2023-01-04"},
{"id":1478,"name":"張三","record":["08:30","18:00"],"recorddate":"2023-01-05"},
{"id":1477,"name":"張三","record":["08:30","18:00"],"recorddate":"2023-01-06"},
{"id":1476,"name":"張三","record":["08:30","18:00"],"recorddate":"2023-01-07"},
{"id":1475,"name":"張三","record":["08:30","18:00"],"recorddate":"2023-01-08"},
{"id":1474,"name":"張三","record":["08:30","18:00"],"recorddate":"2023-01-09"},
{"id":1473,"name":"張三","record":["08:30","18:00"],"recorddate":"2023-01-10"},
{"id":1472,"name":"張三","record":["08:30","18:00"],"recorddate":"2023-01-11"},
{"id":1471,"name":"張三","record":["08:30","18:00"],"recorddate":"2023-01-12"},
{"id":1470,"name":"張三","record":["08:30","18:00"],"recorddate":"2023-01-13"},
{"id":1469,"name":"張三","record":["08:30","18:00"],"recorddate":"2023-01-14"},
{"id":1468,"name":"張三","record":["08:30","18:00"],"recorddate":"2023-01-15"},
{"id":1467,"name":"張三","record":["08:30","18:00"],"recorddate":"2023-01-16"},
{"id":1466,"name":"張三","record":["08:30","18:00"],"recorddate":"2023-01-17"},
{"id":1465,"name":"張三","record":["08:30","18:00"],"recorddate":"2023-01-18"},
{"id":1464,"name":"張三","record":["08:30","18:00"],"recorddate":"2023-01-19"},
{"id":1463,"name":"張三","record":["08:30","18:00"],"recorddate":"2023-01-20"},
{"id":1462,"name":"張三","record":["08:30","18:00"],"recorddate":"2023-01-21"},
{"id":1461,"name":"張三","record":["08:30","18:00"],"recorddate":"2023-01-22"},
{"id":1382,"name":"李四","record":["08:30","18:00"],"recorddate":"2023-01-01"},
{"id":1381,"name":"李四","record":["08:30","18:00"],"recorddate":"2023-01-07"},
{"id":1380,"name":"李四","record":["08:30","18:00"],"recorddate":"2023-01-08"},
{"id":1379,"name":"李四","record":["08:30","18:00"],"recorddate":"2023-01-15"},
{"id":1378,"name":"李四","record":["08:30","18:00"],"recorddate":"2023-01-21"},
{"id":1377,"name":"李四","record":["08:30","18:00"],"recorddate":"2023-01-22"},
{"id":1376,"name":"王五","record":["08:30","18:00"],"recorddate":"2023-01-05"},
{"id":1375,"name":"王五","record":["08:30","18:00"],"recorddate":"2023-01-06"},
{"id":1374,"name":"王五","record":["08:30","18:00"],"recorddate":"2023-01-09"},
{"id":1373,"name":"王五","record":["08:30","18:00"],"recorddate":"2023-01-11"},
{"id":1372,"name":"王五","record":["08:30","18:00"],"recorddate":"2023-01-10"},
{"id":1371,"name":"王五","record":["08:30","18:00"],"recorddate":"2023-01-04"},
{"id":1370,"name":"王五","record":["08:30","18:00"],"recorddate":"2023-01-03"},
{"id":1369,"name":"王五","record":["08:30","18:00"],"recorddate":"2023-01-02"}
]4.7 添加日期列
引入剛才創(chuàng)建好的demo.json文件,導(dǎo)致模擬數(shù)據(jù)。變量tableData用于存儲(chǔ)考勤數(shù)據(jù),變量tableColumn用于存儲(chǔ)表格列數(shù)據(jù),在updateList()函數(shù)執(zhí)行后,獲取全部唯一日期數(shù)據(jù),和全部用戶(hù)數(shù)據(jù),分別存儲(chǔ)到tableData和tableColumn變量中。
由于這里是通過(guò)模擬數(shù)據(jù)實(shí)現(xiàn)的功能效果,后期在項(xiàng)目中,相應(yīng)數(shù)據(jù)是通過(guò)接口查詢(xún)獲取而且的。
<script>
import DemoData from './demo.json'
export default {
data(){
return {
tableData: [],
tableColumn: [
{prop: "name", name: "姓名", width: "80px"},
{prop: "workday", name: "實(shí)際到崗/天", width: "100px"},
]
}
},
created() {
this.updateList();
},
methods: {
//加載列表數(shù)據(jù)
updateList(){
//獲取日期列表
let dateColumn = [],
employeeList = [];
//循環(huán)獲取唯一 列日期 和 唯一 員工信息
DemoData.map(item => {
if(!dateColumn.includes(item.recorddate)){
dateColumn.push(item.recorddate);
}
if(!employeeList.includes(item.name)){
employeeList.push(item.name);
}
});
//升序排序
dateColumn.sort();
//修改列長(zhǎng)度,以免name和workday固定列被替換
this.tableColumn.length = 2;
//追加日期列
this.tableColumn = this.tableColumn.concat(dateColumn.map(item => {
return {
prop: item,
name: item,
width: "100px",
isDate: true
}
}));
}
//end
}
}
</script>以上代碼完成后,日期列則可以正常顯示出來(lái)了,如下圖:

4.8 重組行數(shù)據(jù)
通過(guò)變量employeeList存儲(chǔ)的員工信息,遍歷查詢(xún)模擬數(shù)據(jù)中各自對(duì)應(yīng)的考勤記錄,并通過(guò)變量dateColumn中存儲(chǔ)的日期作為鍵,存儲(chǔ)到對(duì)應(yīng)員工信息中。
<script>
import DemoData from './demo.json'
export default {
data(){
return {
tableData: [],
tableColumn: [
{prop: "name", name: "姓名", width: "80px"},
{prop: "workday", name: "實(shí)際到崗/天", width: "100px"},
]
}
},
created() {
this.updateList();
},
methods: {
//加載列表數(shù)據(jù)
updateList(){
//獲取日期列表
let dateColumn = [],
employeeList = [];
//循環(huán)獲取唯一 列日期 和 唯一 員工信息
DemoData.map(item => {
if(!dateColumn.includes(item.recorddate)){
dateColumn.push(item.recorddate);
}
if(!employeeList.includes(item.name)){
employeeList.push(item.name);
}
});
//升序排序
dateColumn.sort();
//修改列長(zhǎng)度,以免name和workday固定列被替換
this.tableColumn.length = 2;
//追加列
this.tableColumn = this.tableColumn.concat(dateColumn.map(item => {
return {
prop: item,
name: item,
width: "100px",
isDate: true
}
}));
//重組員工考勤數(shù)據(jù),一行顯示考勤記錄
this.tableData = employeeList.map(item => {
let nData = {},
tmp = null,
realWorkSize = 0;
//獲取對(duì)應(yīng)員工的考勤記錄
dateColumn.forEach(key => {
tmp = DemoData.filter(sub => sub.name == item && sub.recorddate == key);
if(tmp.length==1&&tmp[0]['record'].length==2){
//記錄考勤數(shù)據(jù)
nData[key] = tmp[0]['record'][0] + '<br />' + tmp[0]['record'][1];
//保存對(duì)應(yīng)考勤記錄的ID
nData['id_'+key] = tmp[0]['id'];
//統(tǒng)計(jì)到崗天數(shù)
realWorkSize++;
}else{
nData[key] = '-';
}
})
return {
name: item,
workday: realWorkSize,
...nData
}
});
}
//end
}
}
</script>此時(shí)模擬數(shù)據(jù)中考勤記錄都正常顯示在頁(yè)面中了,如下圖:

五、自定義右擊菜單
此時(shí)我們可以來(lái)實(shí)現(xiàn)自定義右擊菜單了,這里只簡(jiǎn)單講解下實(shí)現(xiàn)方法和步驟,如有實(shí)際需求可對(duì)此功能進(jìn)行封裝處理,這里先用散裝代碼實(shí)現(xiàn)此功能。
5.1 準(zhǔn)備工作
首先引入jquery,并且添加禁用右擊菜單的鼠標(biāo)事件,代碼如下:
<script>
import DemoData from './demo.json'
import $ from 'jquery'
//記錄是否懸浮在指定單元格上
let isHoverCell = false;
//記錄懸浮位置考勤記錄對(duì)象
let hoverData = null;
//右擊菜單Dom對(duì)象
let MenuBox = null;
//記錄上一個(gè)數(shù)據(jù)的ID,用于判斷是否需要新打開(kāi)一個(gè)窗口
let tmpPreId = 0;
export default {
data(){
return {
tableData: [],
tableColumn: [
{prop: "name", name: "姓名", width: "80px"},
{prop: "workday", name: "實(shí)際到崗/天", width: "100px"},
]
}
},
created() {
this.updateList();
//右擊菜單事件
window.oncontextmenu = function(e){
if(isHoverCell){
//取消默認(rèn)的瀏覽器自帶右鍵
e.preventDefault();
}
}
//event end
},
methods: {
//...
//end
}
}
</script>綁定oncontextmenu事件后,當(dāng)鼠標(biāo)懸浮在考勤記錄上時(shí),則變量isHoverCell值為true,此時(shí)右擊禁用則會(huì)生效。
5.2 判斷鼠標(biāo)位置
在methods中新建cellAddEvent()函數(shù),將其放到updateList()函數(shù)執(zhí)行結(jié)束位置,延遲100秒再執(zhí)行,以防數(shù)據(jù)未渲染完jquery無(wú)法查詢(xún)到全部考勤記錄的DOM節(jié)點(diǎn)。
另外,考勤數(shù)據(jù)會(huì)因增刪改查等操作,重新渲染,所以每個(gè)單元格綁定事件,也會(huì)在重新渲染后被釋放,需渲染完后重新綁定事件,故cellAddEvent()函數(shù)應(yīng)放應(yīng)updateList()函數(shù)內(nèi)執(zhí)行。
<script>
import DemoData from './demo.json'
import $ from 'jquery'
//記錄是否懸浮在指定單元格上
let isHoverCell = false;
//記錄懸浮位置考勤記錄對(duì)象
let hoverData = null;
//右擊菜單Dom對(duì)象
let MenuBox = null;
//記錄上一個(gè)數(shù)據(jù)的ID,用于判斷是否需要新打開(kāi)一個(gè)窗口
let tmpPreId = 0;
export default {
data(){
return {
tableData: [],
tableColumn: [
{prop: "name", name: "姓名", width: "80px"},
{prop: "workday", name: "實(shí)際到崗/天", width: "100px"},
]
}
},
created() {
this.updateList();
//右擊菜單事件
window.oncontextmenu = function(e){
if(isHoverCell){
//取消默認(rèn)的瀏覽器自帶右鍵
e.preventDefault();
}
}
//event end
},
methods: {
/**
* 為考勤記錄添加相應(yīng)監(jiān)聽(tīng)事件
*/
cellAddEvent(){
let that = this,
propData = "";
//懸浮事件
$('.date-cell').hover(function(){
isHoverCell = true;
let id = $(this).data('id'),
filterData = DemoData.filter(item => item.id == id);
if(filterData.length==1){
hoverData = {
prop: $(this).data('prop'),
data: filterData[0]
}
}
//if end
}, function(){
isHoverCell = false;
hoverData = null;
});
},
//加載列表數(shù)據(jù)
updateList(){
//獲取日期列表
let dateColumn = [],
employeeList = [];
//循環(huán)獲取唯一 列日期 和 唯一 員工信息
DemoData.map(item => {
if(!dateColumn.includes(item.recorddate)){
dateColumn.push(item.recorddate);
}
if(!employeeList.includes(item.name)){
employeeList.push(item.name);
}
});
//升序排序
dateColumn.sort();
//修改列長(zhǎng)度,以免name和workday固定列被替換
this.tableColumn.length = 2;
//追加列
this.tableColumn = this.tableColumn.concat(dateColumn.map(item => {
return {
prop: item,
name: item,
width: "100px",
isDate: true
}
}));
//重組員工考勤數(shù)據(jù),一行顯示考勤記錄
this.tableData = employeeList.map(item => {
let nData = {},
tmp = null,
realWorkSize = 0;
//獲取對(duì)應(yīng)員工的考勤記錄
dateColumn.forEach(key => {
tmp = DemoData.filter(sub => sub.name == item && sub.recorddate == key);
if(tmp.length==1&&tmp[0]['record'].length==2){
//記錄考勤數(shù)據(jù)
nData[key] = tmp[0]['record'][0] + '<br />' + tmp[0]['record'][1];
//保存對(duì)應(yīng)考勤記錄的ID
nData['id_'+key] = tmp[0]['id'];
//統(tǒng)計(jì)到崗天數(shù)
realWorkSize++;
}else{
nData[key] = '-';
}
})
return {
name: item,
workday: realWorkSize,
...nData
}
});
setTimeout(() => {
this.cellAddEvent();
}, 100);
}
//end
}
}
</script>此時(shí)大家會(huì)發(fā)現(xiàn),鼠標(biāo)在頁(yè)面其他位置可以正常右擊顯示默認(rèn)菜單,但放到考勤記錄上時(shí),右擊菜單則失效無(wú)法顯示了。
5.3 添加自定義菜單
當(dāng)變量isHoverCell為true時(shí),右擊執(zhí)行rightMenuInitial()函數(shù),通過(guò)jquery創(chuàng)建菜單容器后,追加到body中。此時(shí)右擊則能看到刪除按鈕了。
<script>
import DemoData from './demo.json'
import $ from 'jquery'
//記錄是否懸浮在指定單元格上
let isHoverCell = false;
//記錄懸浮位置考勤記錄對(duì)象
let hoverData = null;
//右擊菜單Dom對(duì)象
let MenuBox = null;
//記錄上一個(gè)數(shù)據(jù)的ID,用于判斷是否需要新打開(kāi)一個(gè)窗口
let tmpPreId = 0;
export default {
data(){
return {
tableData: [],
tableColumn: [
{prop: "name", name: "姓名", width: "80px"},
{prop: "workday", name: "實(shí)際到崗/天", width: "100px"},
]
}
},
created() {
this.updateList();
let that = this;
//右擊菜單事件
window.oncontextmenu = function(e){
if(isHoverCell){
//取消默認(rèn)的瀏覽器自帶右鍵
e.preventDefault();
that.rightMenuInitial(e);
}
}
//event end
},
methods: {
/**
* 右擊初始化彈框事件
* @param e 右擊事件
*/
rightMenuInitial(e){
if(null==hoverData||'undefined'===typeof hoverData.data){
this.$message.info("數(shù)據(jù)讀取失敗,刷新后再試~");
return;
}
if(null!=MenuBox) {
//上一個(gè)右擊區(qū)域未變化,則結(jié)束后續(xù)操作
if(tmpPreId==hoverData.data.id) return;
};
//記錄當(dāng)前ID
tmpPreId = hoverData.data.id;
//創(chuàng)建右擊菜單容器
MenuBox = $('<div />').addClass('menu-box');
let that = this,
listData = [
{id: 1, name: "刪除", style: "delete"}
],
ulBox = $('<ul />').addClass('list');
//添加列表
MenuBox.append(ulBox);
//循環(huán)生成右擊菜單列表
for(var i in listData){
ulBox.append($('<li />').text(listData[i]['name']).addClass(listData[i]['style']));
}
//for end
//添加位置
MenuBox.css({
'position': 'absolute',
'left': e.clientX,
'top': e.clientY,
'z-index': 10
});
ulBox.hover(function(){
isHoverCell = true;
}, function(){
isHoverCell = false;
});
/**
* 添加刪除事件
*/
ulBox.on('click', 'li.delete', function(){
that.$confirm('確定刪除'+ hoverData.data.name + '的' + hoverData.prop+'考勤記錄嗎?', '提示', {
confirmButtonText: '確定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
//查詢(xún)?cè)磾?shù)據(jù)對(duì)應(yīng)位置,將其刪除(這里Demo演示,真實(shí)環(huán)境需要將刪除數(shù)據(jù)ID傳給后臺(tái)進(jìn)行操作)
let index = DemoData.indexOf(hoverData.data);
DemoData.splice(index, 1);
that.updateList();
}).catch(() => {
that.$message({
type: 'info',
message: '已取消刪除'
});
});
});
//追加到頁(yè)面中
$('body').append(MenuBox);
},
//...
//end
}
}
</script>5.4 增加移除菜單功能
增加removeMenuBox()函數(shù),用于在不同情況下,需要移除自定義菜單。代碼如下:
<script>
import DemoData from './demo.json'
import $ from 'jquery'
//記錄是否懸浮在指定單元格上
let isHoverCell = false;
//記錄懸浮位置考勤記錄對(duì)象
let hoverData = null;
//右擊菜單Dom對(duì)象
let MenuBox = null;
//記錄上一個(gè)數(shù)據(jù)的ID,用于判斷是否需要新打開(kāi)一個(gè)窗口
let tmpPreId = 0;
export default {
data(){
return {
tableData: [],
tableColumn: [
{prop: "name", name: "姓名", width: "80px"},
{prop: "workday", name: "實(shí)際到崗/天", width: "100px"},
]
}
},
created() {
this.updateList();
let that = this;
//右擊菜單事件
window.oncontextmenu = function(e){
if(isHoverCell){
//取消默認(rèn)的瀏覽器自帶右鍵
e.preventDefault();
that.rightMenuInitial(e);
}
}
//event end
},
methods: {
/**
* 刪除右擊菜單
* @date 2023/1/30
*/
removeMenuBox(){
if(!MenuBox) return;
MenuBox.remove();
MenuBox = null;
},
/**
* 右擊初始化彈框事件
* @param e 右擊事件
*/
rightMenuInitial(e){
if(null==hoverData||'undefined'===typeof hoverData.data){
this.$message.info("數(shù)據(jù)讀取失敗,刷新后再試~");
return;
}
if(null!=MenuBox) {
this.removeMenuBox();
//上一個(gè)右擊區(qū)域未變化,則結(jié)束后續(xù)操作
if(tmpPreId==hoverData.data.id) return;
};
//記錄當(dāng)前ID
tmpPreId = hoverData.data.id;
//創(chuàng)建右擊菜單容器
MenuBox = $('<div />').addClass('menu-box');
let that = this,
listData = [
{id: 1, name: "刪除", style: "delete"}
],
ulBox = $('<ul />').addClass('list');
//添加列表
MenuBox.append(ulBox);
//循環(huán)生成右擊菜單列表
for(var i in listData){
ulBox.append($('<li />').text(listData[i]['name']).addClass(listData[i]['style']));
}
//for end
//添加位置
MenuBox.css({
'position': 'absolute',
'left': e.clientX,
'top': e.clientY,
'z-index': 10
});
//自定義菜單懸浮事件監(jiān)聽(tīng)
ulBox.hover(function(){
isHoverCell = true;
}, function(){
isHoverCell = false;
});
/**
* 添加刪除事件
*/
ulBox.on('click', 'li.delete', function(){
that.$confirm('確定刪除'+ hoverData.data.name + '的' + hoverData.prop+'考勤記錄嗎?', '提示', {
confirmButtonText: '確定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
//查詢(xún)?cè)磾?shù)據(jù)對(duì)應(yīng)位置,將其刪除(這里Demo演示,真實(shí)環(huán)境需要將刪除數(shù)據(jù)ID傳給后臺(tái)進(jìn)行操作)
let index = DemoData.indexOf(hoverData.data);
DemoData.splice(index, 1);
that.removeMenuBox();
that.updateList();
}).catch(() => {
that.removeMenuBox();
that.$message({
type: 'info',
message: '已取消刪除'
});
});
});
//追加到頁(yè)面中
$('body').append(MenuBox);
},
/**
* 為考勤記錄添加相應(yīng)監(jiān)聽(tīng)事件
*/
cellAddEvent(){
let that = this,
propData = "";
//懸浮事件
$('.date-cell').hover(function(){
isHoverCell = true;
let id = $(this).data('id'),
filterData = DemoData.filter(item => item.id == id);
if(filterData.length==1){
hoverData = {
prop: $(this).data('prop'),
data: filterData[0]
}
}
// console.log('id', id);e
//if end
}, function(){
isHoverCell = false;
});
//鼠標(biāo)移出事件,關(guān)閉刪除菜單
$(document).off('click').on('click', function(){
if(!isHoverCell&&null!=MenuBox){
that.removeMenuBox();
}
});
},
//加載列表數(shù)據(jù)
updateList(){
//獲取日期列表
let dateColumn = [],
employeeList = [];
//循環(huán)獲取唯一 列日期 和 唯一 員工信息
DemoData.map(item => {
if(!dateColumn.includes(item.recorddate)){
dateColumn.push(item.recorddate);
}
if(!employeeList.includes(item.name)){
employeeList.push(item.name);
}
});
//升序排序
dateColumn.sort();
//修改列長(zhǎng)度,以免name和workday固定列被替換
this.tableColumn.length = 2;
//追加列
this.tableColumn = this.tableColumn.concat(dateColumn.map(item => {
return {
prop: item,
name: item,
width: "100px",
isDate: true
}
}));
//重組員工考勤數(shù)據(jù),一行顯示考勤記錄
this.tableData = employeeList.map(item => {
let nData = {},
tmp = null,
realWorkSize = 0;
//獲取對(duì)應(yīng)員工的考勤記錄
dateColumn.forEach(key => {
tmp = DemoData.filter(sub => sub.name == item && sub.recorddate == key);
if(tmp.length==1&&tmp[0]['record'].length==2){
//記錄考勤數(shù)據(jù)
nData[key] = tmp[0]['record'][0] + '<br />' + tmp[0]['record'][1];
//保存對(duì)應(yīng)考勤記錄的ID
nData['id_'+key] = tmp[0]['id'];
//統(tǒng)計(jì)到崗天數(shù)
realWorkSize++;
}else{
nData[key] = '-';
}
})
return {
name: item,
workday: realWorkSize,
...nData
}
});
setTimeout(() => {
this.cellAddEvent();
}, 100);
}
//end
}
}
</script>5.5 追加菜單內(nèi)容
在自定義右擊菜單時(shí),已預(yù)留了增加更多菜單項(xiàng)位置,如下代碼,在變量listData中添加菜單內(nèi)容即可。
rightMenuInitial(e){
if(null==hoverData||'undefined'===typeof hoverData.data){
this.$message.info("數(shù)據(jù)讀取失敗,刷新后再試~");
return;
}
if(null!=MenuBox) {
this.removeMenuBox();
//上一個(gè)右擊區(qū)域未變化,則結(jié)束后續(xù)操作
if(tmpPreId==hoverData.data.id) return;
};
//記錄當(dāng)前ID
tmpPreId = hoverData.data.id;
//創(chuàng)建右擊菜單容器
MenuBox = $('<div />').addClass('menu-box');
let that = this,
listData = [
{id: 1, name: "編輯", style: "edit"},
{id: 2, name: "刪除", style: "delete"}
],
ulBox = $('<ul />').addClass('list');
//...
}如下圖,右擊時(shí)自定義菜單中則出現(xiàn)“編輯”項(xiàng)了,這塊功能這里就不作詳解,大家可以自行操作。這里就簡(jiǎn)單講解下自定義右擊菜單和刪除功能,僅供大家參考,如有不足之處請(qǐng)見(jiàn)諒!

到此這篇關(guān)于Vue實(shí)現(xiàn)自定義右擊刪除菜單的示例的文章就介紹到這了,更多相關(guān)Vue 右擊刪除菜單內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue3?中?watch?與?watchEffect?區(qū)別及用法小結(jié)
這篇文章主要介紹了Vue3?中?watch?與?watchEffect?有什么區(qū)別?watch中需要指明監(jiān)視的屬性,也需要指明監(jiān)視的回調(diào),而watchEffect中不需要指明監(jiān)視的屬性,只需要指明監(jiān)視的回調(diào),回調(diào)函數(shù)中用到哪個(gè)屬性,就監(jiān)視哪個(gè)屬性,本文給大家詳細(xì)介紹,需要的朋友參考下2022-06-06
vue級(jí)聯(lián)選擇器的getCheckedNodes使用方式
這篇文章主要介紹了vue級(jí)聯(lián)選擇器的getCheckedNodes使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04
Vue3根據(jù)動(dòng)態(tài)字段綁定v-model的操作代碼
最近在學(xué)習(xí)vue技術(shù),開(kāi)發(fā)表格的時(shí)候,想把表格做成組件,那查詢(xún)條件就需要?jiǎng)討B(tài)生成,這就遇到一個(gè)問(wèn)題,vue怎么動(dòng)態(tài)給v-model變量值,本文通過(guò)實(shí)例代碼給大家介紹,對(duì)Vue3動(dòng)態(tài)綁定v-model實(shí)例代碼感興趣的朋友一起看看吧2022-10-10
element-plus中el-table點(diǎn)擊單行修改背景色方法
這篇文章主要給大家介紹了關(guān)于element-plus中el-table點(diǎn)擊單行修改背景色的相關(guān)資料,這是產(chǎn)品新加了的一個(gè)需求,分享給同樣遇到這個(gè)需求的朋友,需要的朋友可以參考下2023-07-07
利用Vue實(shí)現(xiàn)數(shù)字翻滾動(dòng)畫(huà)效果展示
這篇文章主要介紹了利用Vue實(shí)現(xiàn)數(shù)字翻滾動(dòng)畫(huà)效果,通過(guò)Vue的響應(yīng)式數(shù)據(jù)更新結(jié)合CSS3的動(dòng)畫(huà)效果,我們可以實(shí)現(xiàn)非??犰诺臄?shù)字翻滾效果,給數(shù)據(jù)可視化帶來(lái)更多動(dòng)感和吸引力,需要的朋友參考下吧2024-04-04
vue3使用useDialog實(shí)現(xiàn)對(duì)話(huà)框的示例代碼
在日常開(kāi)發(fā)中,彈窗是常見(jiàn)的一個(gè)功能,本文主要介紹了vue3使用useDialog實(shí)現(xiàn)對(duì)話(huà)框的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01
Vue項(xiàng)目History模式404問(wèn)題解決方法
本文主要解決Vue項(xiàng)目使用History模式發(fā)布到服務(wù)器Nginx上刷新頁(yè)面404問(wèn)題。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-10-10
vue如何根據(jù)網(wǎng)站路由判斷頁(yè)面主題色詳解
這篇文章主要給大家介紹了關(guān)于vue如何根據(jù)網(wǎng)站路由判斷頁(yè)面主題色的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-11-11

