vue 自定義右鍵樣式

前言

最近用python寫了個小說程序的api,想着用vue作個系統管理數據,腦子裏出現的是這個畫面:

image

可是這種樣式的管理後臺已經作了太多了,已經審美疲勞,後面又想了一種類操做系統的UI界面:

主要是靠雙擊右鍵來操做,可操做多個模態框,跟操做windows相似,接下來在裏面拆出一個功能塊來寫一篇文章,就是自定義系統默認的右鍵
自定義右鍵操做有五個步驟:
  1. 阻止默認右鍵。
  2. 獲取當前右鍵點擊時的x/y座標,及id
  3. 自定義右鍵菜單樣式及內容,定位在指定的位置後顯示。
  4. 返回對應點擊目錄的事件如:查看刪除編輯
  5. 在任何地方點擊左鍵時隱藏右鍵菜單
關鍵方法:
@contextmenu.prevent
複製代碼

這個是vue內置的,點擊右鍵(阻止默認右鍵的默認行爲)的一個回調方法,他返回了一大串東西這裏我用到的是這兩個(用於定位顯示菜單的x,y位置)javascript

image

可是這裏會出現一個問題:css

操做1:
<!--template-->
<ul> <li class="role_list" v-for="(item,index) in role" :key="index" @contextmenu.prevent="rightClick"> <img :src="item.head_portrait" alt=""> <p>{{item.name}}</p> </li> </ul> <!--script--> methods:{ rightClick(e){ <!--這裏只能拿到座標,但拿不到點擊對應的id--> console.log(e) } } 複製代碼
操做2:
<!--template-->
<ul> <li class="role_list" v-for="(item,index) in role" :key="index" @contextmenu.prevent="rightClick(item.id)"> <img :src="item.head_portrait" alt=""> <p>{{item.name}}</p> </li> </ul> <!--script--> methods:{ rightClick(id){ <!--這裏只能拿到id,但拿不到點擊對應的座標--> console.log(id) } } 複製代碼
解決方法:

x_indexy_index 是儲存在data中的,用於定位模態框位置。
ctrlId 用於給接口處理的依據
showMenu 用於判斷是否顯示右鍵菜單前端

<!--template-->
<ul> <li class="role_list" v-for="(item,index) in role" :key="index" @contextmenu.prevent="(e)=>{ x_index = e.layerX; y_index = e.layerY; ctrlId = item.id; showMenu = true; }"> <img :src="item.head_portrait" alt=""> <p>{{item.name}}</p> </li> </ul> 複製代碼

須要的參數(x,y,id)都具有了,由於右鍵操做不少地方都用到了,因此封裝成了一個組件vue

right_menu.vue 組件代碼

參數名 註釋
x x座標
y y座標
showMenu 顯示狀態
<template>
	<div v-if="show"
	     class="menu_style" 
	     :style="{top:y+'px',left:x+'px'}">
		<ul>
			<!-- 分別傳遞事件給父元素調用 -->
			<li @click="()=>{$emit('open')}">打開</li>
			<li @click="()=>{$emit('update')}">編輯</li>
			<li @click="()=>{$emit('del')}">刪除</li>
		</ul>
	</div>
</template>
<script>
	export default{
		name:'right_menu',
		props:{
			x:{
				type:[Number],
				default:0
			},
			y:{
				type:[Number],
				default:0
			},
			showMenu:{
				type:[Boolean],
				default:false
			}
		},
		data(){
			return {
				show:false,
			}
		},
		methods:{
			// 點擊別處時隱藏目錄,並傳遞一個關閉事件
			closeMenu(e){
				this.show = false;
				this.$emit("close",false)
			},
		},
		mounted(){
			// 監聽body上的點擊
			document.querySelector("body").addEventListener("click",this.closeMenu)
		},
		beforeDestroy(){
			// 移除監聽
			document.querySelector("body").removeEventListener("click",this.closeMenu)
		},
		watch:{
			// 監聽,保持顯示狀態與父元素一致
			showMenu(val){
				this.show = val;
			}
		},
	}
</script>
<style scoped>
	.menu_style{
		position: absolute;
		width: 150px;
		background-color: #fff;
		border-radius: 2px;
		box-shadow: 2px 2px 14px #d0d0d0;
	}
	.menu_style>ul>li{
		text-indent: 25px;
		height: 38px;
		line-height: 38px;
		border-bottom: 1px dashed #f0f0f0;
		cursor: pointer;
	}
	.menu_style>ul>li:hover{
		background: #E0EEFF;
	}
</style>
複製代碼
組件使用
<template>
    <div class="modal_data_box"> <ul> <li class="role_list" v-for="(item,index) in role" :key="index" @contextmenu.prevent="(e)=>{ x_index = e.layerX; y_index = e.layerY; ctrlId = item.id; showMenu = true; }"> <img :src="item.head_portrait" alt=""> <p>{{item.name}}</p> </li> </ul> <!--組件--> <right-menu :x="x_index" :y="y_index" :showMenu="showMenu" @close="closeMenu" @open="openDetail" @del="delAttr" @update="updateArr"> </right-menu> </div> </template> <script> // 導入組件 import rightMenu from '../module/right_menu.vue'; export default{ name:"roleModal", components:{rightMenu}, data(){ return { x_index:0, y_index:0, ctrlId:'', showMenu:false, role:[], } }, methods:{ //關閉回調  closeMenu(state){ console.log('關閉') this.showMenu = state; }, //打開詳情回調  openDetail(){ console.log('編輯') }, //刪除回調  delAttr(){ console.log('刪除') }, //編輯回調  updateArr(){ console.log('編輯') }, } } </script> 複製代碼
其他文章:

前端經常使用功能小計(持續更新)java

css圖片以最長邊顯示python

flask多圖片儲存優化flask

flask 實現token機制windows

相關文章
相關標籤/搜索