предисловие
При щелчке правой кнопкой мыши в браузере будет меню по умолчанию. В моем проекте с открытым исходным кодом необходимо настроить контекстное меню. Я нашел соответствующие пакеты в библиотеке npm и обнаружил, что все они реализованы в виде компонентов.Я чувствую, что этот подход слишком громоздкий.
Итак, я задался вопросом, могу ли я связать его с таким элементом, как встроенные инструкции Vue, и щелкнуть правой кнопкой мыши по этому элементу, чтобы отобразить контекстное меню, что было бы намного удобнее.
После прочтения пользовательского документа с инструкциями Vue, после долгих метаний, я наконец осуществил свою идею. В этой статье я поделюсь с вами своими идеями реализации и процессом. Заинтересованные разработчики могут прочитать эту статью.
Реализовать идеи
В Vue есть много встроенных директив, например:v-if,v-for,v-model, в дополнение к этим встроенным директивам, это также позволяет нашим разработчикам регистрировать свои собственные директивы для достижения желаемого эффекта Разработчики, которые не знакомы с пользовательскими директивами Vue, могут сначала просмотреть документацию:пользовательская директива.
Далее позвольте мне рассказать вам о моих идеях реализации:
-
Макет контекстного меню, стиль записи
-
Определите данные, необходимые для контекстного меню в vuex.
-
Зарегистрируйте директиву глобально, с именем
rightClick -
Перехватить связанный элемент
oncontextmenuсобытие, которое обрабатывает значение, переданное компонентом -
Обновите данные контекстного меню в vuex, чтобы вызвать отображение контекстного меню.
Процесс реализации
Далее я поделюсь с вами своим процессом реализации.
Стиль макета правой кнопкой мыши
Давайте сначала посмотрим, какие данные нужны этому компоненту, чтобы он отображался там, где находится мышь.
- Его явное и скрытое состояние, а именно: элемент css
displayАтрибуты - его местоположение, то есть: элемент css
left,topАтрибуты - Его текстовые данные, то есть содержимое, которое должно отображаться в контекстном меню, отображаются через
v-forоказывать - Его функция обработки событий, а именно: обработка событий, которая будет выполняться при выборе параметра в контекстном меню.
Находим общий компонент в проекте, чтобы убедиться, что этот компонент будет рендериться, в компонентеtemplateДобавьте в него следующий код.
<!--右键菜单-->
<div
id="rightMenuDom"
class="right-menu"
:style="{
display: rightMenuStatus,
top: rightMenuTop,
left: rightMenuLeft
}"
>
<ul>
<!--分为2组渲染-->
<li>
<span
v-for="item in rightMenuList"
:key="item.id"
v-show="item.id <= 3"
@click="item.handler"
>{{ item.text }}
</span>
</li>
<li>
<span
v-for="item in rightMenuList"
:key="item.id"
v-show="item.id > 3"
@click="item.handler"
>{{ item.text }}
</span>
</li>
</ul>
</div>
</div>
Впоследствии в компонентеmountedДобавьте глобальный прослушиватель событий щелчка в жизненном цикле, цель которого состоит в том, чтобы скрыть контекстное меню после щелчка в любом месте.
mounted() {
// 监听全局点击事件
document.addEventListener("click", () => {
// 隐藏右键菜单
this.$store.commit("updateRightMenuStatus", {
status: "none",
left: "0px",
top: "0px"
});
});
}
Далее в компонентеcomputedПолучите данные, определенные в Vuex, для рендеринга контекстного меню.
computed: {
// 右键菜单显隐状态
rightMenuStatus(): string {
return this.$store.state.rightMenu.status;
},
// 右键菜单距离浏览器顶部高度
rightMenuTop(): string {
return this.$store.state.rightMenu.top;
},
// 右键菜单距离浏览器左边长度
rightMenuLeft(): string {
return this.$store.state.rightMenu.left;
},
// 右键菜单列表内容
rightMenuList(): [] {
return this.$store.state.rightMenu.list;
}
}
Наконец, напишите для него стили css.
// 右键菜单样式
.right-menu {
position: fixed;
left: 0;
top: 0;
width: 166px;
height: auto;
background-color: rgb(242, 242, 242);
border: solid 1px #C2C1C2;
box-shadow: 0 10px 10px #C2C1C2;
display: none;
border-radius: 5px;
ul {
padding: 0;
margin: 0;
font-size: 15px;
li {
list-style: none;
box-sizing: border-box;
padding: 6px 0;
border-bottom: 1px solid rgb(216, 216, 217);
&:nth-child(1) {
padding-top: 2px;
}
&:nth-last-child(1) {
border-bottom: none;
}
span {
display: block;
height: 20px;
line-height: 20px;
padding-left: 16px;
&:hover {
background-color: #0070F5;
cursor: pointer;
color: #FFFFFF;
}
}
}
}
}
Определение данных в Vuex
В файле конфигурации vuex найдитеstateсвойства, добавьте следующий код.
-
statusЯвное и скрытое состояние компонента -
topРасстояние компонента от верхней части видимой области браузера -
leftРасстояние от левого края видимой области браузера -
listТекстовые данные, необходимые компоненту и соответствующему обработчику событий.
rightMenu: {
status: "none",
top: "0px",
left: "0px",
list: []
}
затем вmutationsДобавьте метод для обновления данных в .
// 更新右键菜单数据
updateRightMenuStatus(state, menuObj: rightMenuAttribute) {
state.rightMenu.status = menuObj.status;
state.rightMenu.top = menuObj.top;
state.rightMenu.left = menuObj.left;
state.rightMenu.list = menuObj.list;
}
Зарегистрировать глобальную директиву
Наш входной файл в vue:main.ts, зарегистрировать глобальную директивуrightClick.
-
elЭлемент, который связывает директиву для нас -
bindingСодержит параметры, переданные командой
app.directive("rightClick", (el, binding) => {
});
Перехватывать параметры инструкции обработки события щелчка правой кнопкой мыши
Выше мы зарегистрировали глобальную инструкцию, нам нужно переписать ее событие щелчка для элемента, привязанного к инструкции внутри ее функции, и обработать переданные инструкцией параметры.
- поместить объекты события в массив
- Поместите текстовые данные каждого контекстного меню и соответствующую функцию обработки времени в массив json.
- Чтобы получить позицию щелчка мыши, используйте
commitОбновите соответствующие данные в Vuex и отобразите страницу.
el.oncontextmenu = function(e: MouseEvent) {
const textArray = binding.value.text;
const handlerObj = binding.value.handler;
// 事件处理数组
const handlerArray = [];
// 处理好的右键菜单
const menuList = [];
// 将事件处理函数放入数组中
for (const key in handlerObj) {
handlerArray.push(handlerObj[key]);
}
// 追加右键菜单数据
for (let i = 0; i < textArray.length; i++) {
// 右键菜单对象, 添加名称
const menuObj = {
text: textArray[i],
handler: handlerArray[i],
id: i + 1
};
menuList.push(menuObj);
}
// 鼠标点的坐标
const oX = e.clientX;
const oY = e.clientY;
// 右键菜单出现后的位置
store.commit("updateRightMenuStatus", {
status: "block",
left: oX + "px",
top: oY + "px",
list: menuList
});
return false;
};
Использование директив в компонентах
После завершения операции мы реализовали пользовательскую команду меню прямо, а затем посмотрим, как мы используем регистр команды в сборке.
в контексте, где вы хотите связать контекстное менюhtmlдобавить элементv-right-click,Следующее:
<li
class="row-panel"
v-right-click="rightMenuObj"
>
</li>
в компонентеdataОпределите данные, необходимые в контекстном меню вrightMenuObj.
// 右键菜单对象,菜单内容和处理事件
rightMenuObj: {
text: [
"查看资料",
"复制用户id",
"移除该会话",
"在联系人中查看",
"在单聊窗口中打开",
"会话置顶"
],
handler: {
checkingData() {
console.log("查看资料点击事件");
},
copyId() {
console.log("复制用户id点击事件");
},
removeItem() {
console.log("移除会话点击事件");
},
showContact() {
console.log("在联系人中查看");
},
showSingleChat() {
console.log("在单聊窗口中打开");
},
topConversation() {
console.log("会话置顶");
}
}
}
Затем мы можем запустить, чтобы увидеть эффект, как показано ниже, мы успешно достигли желаемого эффекта.
кодовый адрес
Адрес GitHub компонентов, используемых в демонстрации в этой статье, выглядит следующим образом:
напиши в конце
- Если в статье есть ошибки, исправьте их в комментариях, если статья вам поможет, ставьте лайк и подписывайтесь 😊
- Эта статья была впервые опубликована на Наггетс, перепечатка без разрешения запрещена 💌