preface

Pure boredom, I guess, and then a whim.

I have developed a web-based checkout system before. I also implemented retail software earlier, and usually the cashier seldom used the mouse in order to go to the cashier’s register more quickly in stores. It’s all keyboard. But there is a problem with Web operating system pages. It’s your TAB, it’s not very convenient. And then we have the list of items that we need to go back to by keyboard. Using a mouse, in some stores where sales are in the tens of thousands a day, is very tiring and inefficient. This plug-in is also developed to solve this problem.

At present, we have achieved the basic up, down and around, which belongs to the preliminary completion. Without actual business practice. But I think it’s OK.

Source code address: github.com/ht-sauce/dr…

Principle:

First, we want to select the DOM element above the keyboard. It has its own tap, up, down, left, and so on, and you can also use tabIndex. But none of this makes the operation uniform and convenient. The rules are confusing, and we all know that div has no focus state.

So if we want to do that, then we have to build our own wheels. We define and implement this set of rules ourselves.

1, listen to the keyboard up, down and left

2. Move data as elements move up, down, left, and right.

If it was jquery, it would have been a lot of trouble.

Move left and right

Moving left and right is easy. We just need to add or subtract the index of the array. So the code is not simple.

The same way we can manipulate elements up and down. But my goal is universal. So we are governed by established rules.

Defines the element structure of the inserted array

This.dhtsetlist ({bindData: value, // bindData self: this, // select: false, // if selected})Copy the code

It’s actually a little bit easier to see here, but the first one is the bound data. The second is the current instance of vue itself. The third one is state, you can ignore it.

The order in which you insert determines the order in which you move left or right

Move up and down

The most troublesome thing about moving up and down is that we can’t move by the index of the array. The element itself is moved up and down.

Code principle explanation:

1. Filter elements of the same level

2, the upper filter out lower than their own, lower filter higher than their own

3. Sort the smallest element from the top to the bottom.

4. If there is the same Y-axis data up and down, compare the size of X and get the minimum X and return it. If there are more than one X, return the first one by default

// topOrbottomMove(type) {let currentIndex = this.lastTimeli () const list = this.list // CurrentLi = list[currentIndex] const currentLiDom = CurrentLi.self.$el.getBoundingClientRect() const currentY =  currentLiDom.y const currentX = currentLiDom.x const relativeList = [] list.forEach((item, index) => { const { y, x } = item.self.$el.getBoundingClientRect() relativeList.push({ li: item, y: currentY - y, x: Math.abs(currentX -x), index,})}) // Eliminate = relativelist. filter(item => item.y! == 0) if (type === 'top') {// Eliminate = eliminate. Filter (item => item.y > 0) if (topEliminate. Length === 0) {this.sendEmit({item: list[currentIndex], index: currentIndex }) } else { topEliminate.sort((a, b) => a.y - b.y) const xArr = topEliminate.filter(item => item.y === topEliminate[0].y) if (xArr.length > 1) { xArr.sort((a, b) => a.x - b.x) this.sendEmit({ item: xArr[0], index: xArr[0].index }) } else { this.sendEmit({ item: xArr[0], index: XArr [0].index})}}} if (type === 'bottom') {// Const bottomEliminate = eliminate. Filter (item => item.y < 0) if (bottomEliminate. Length === 0) {this.sendEmit({item: list[currentIndex], index: currentIndex }) } else { bottomEliminate.sort((a, b) => b.y - a.y) const xArr = bottomEliminate.filter(item => item.y === bottomEliminate[0].y) if (xArr.length > 1) { xArr.sort((a, b) => a.x - b.x) this.sendEmit({ item: xArr[0], index: xArr[0].index }) } else { this.sendEmit({ item: xArr[0], index: xArr[0].index }) } } } },Copy the code

use

Yesterday I read the article was greatly promoted by the Nuggets home page, sorry too fool. Here’s how to use it.

Core usage:

RichOperate: () => import('@/components/CustomCom/RichOperate/index'),
Copy the code

This is the core of the component and exposes the props and a provide distributed dhtSetList function, which itself takes care of whether the current list of actions is duplicated

This code determines whether your component itself is duplicated

This.list. forEach(item => {if (item.self === self) {item.bindData = bindData alike = true}})Copy the code

And then next to the source file I gave you is an Item file, which is a child component. It is generally recommended that you encapsulate your content in this way.

<template> <div class="rich-operate-item" ref="richOperateItem"> <slot></slot> </div> </template> <script> export default { name: 'RichOperateItem', inject: ['dhtSetList'], props: { value: Null, // Current bound data}, data() {return {select: false,}}, watch: {value: {deep: true, immediate: Handler (value) {this.dhtSetList({bindData: value, // bindData self: this, // select: If false, / / selected})},},}, mounted () {},} < / scriptCopy the code

Import for RichOperateItme: () = > import (‘ @ / components/CustomCom RichOperate/item ‘),

And when you finally use it, it looks like this

<rich-operate switch :index="5" class="test">
  <rich-operate-itme :value="shiyan">
    <div class="ceshi"></div>
  </rich-operate-itme>
  <rich-operate-itme>
    <div class="ceshi"></div>
  </rich-operate-itme>
</rich-operate>
Copy the code

But there is a problem, and I don’t know if there is an impact on the structure of the components themselves in the component library.

If it has an impact, then it is recommended

This.dhtsetlist ({bindData: value, // bindData self: this, // select: false, // if selected})Copy the code

But there are problems with this. I’m passing in the component itself this. The purpose of this is to automatically bind dom nodes once vuedom rendering is complete.

That’s the main thing. For props, check the source code. I’m used to writing comments. They’re pretty comprehensive.

conclusion

The basic principle is pretty simple.

Note that in order to ensure that each sub-component uses provide and Inject for data distribution. In the example, a single child component is defined, but as long as the data is passed according to the rules, there is no problem.

Note that provide and inject data distribution will result in global existence. This means that all descendant components can get the contents of Inject.

The main idea is to provide an idea. And give some source code.

This year is oneself enough capricious, too proud. Life is still shaky, but my next major goal is vue3 and typescript. Use a combination of the two.