When is it packaged as a component? When to encapsulate instructions?

In general, if you want to encapsulate code that contains a lot of HTML, you need to use components, whereas if you only operate on the root DOM of a DOM/ component, you can choose to encapsulate instructions.

Gestures such as “drag and drop” only recognize the “mouse/touch” on an element/component and do not involve DOM manipulation, so select “instruction” for encapsulation here.

Final goal (V-touch instruction)

Take a look at the target and analyze it.

// main.js
import VTouch from '@any-touch/vue3';
/ /... omit
const app = createApp(App);
app.mountd('#app');
app.use(VTouch);
Copy the code
<template>
    <u-component
        v-touch
        @tap="onTap"
        @swipe="onSwipe"
        @press="onPress"
        @pan="onPan"
        @pinch="onPinch"
        @rotate="onRotate"
    >
    </u-component>
</template>
Copy the code
  1. Now that want to useapp.useInitialization, then we need to package into the VUE plug-in, plug-in is inherent format, we develop later write.
  2. Support for gestures is required, using the any-touch js gesture recognition library without dependencies.

Knowledge points (🚀 tips)

In VUE, custom DOM events can be received directly through the “@” syntax, so we can actually implement any “xx” event ourselves and end up listening through “@xx”.

const event = new Event('xx');
this.$refs.xxEl.dispatchEvent(event);
Copy the code

Gesture events that are triggered within ‘any-touch’ are native DOM events that are triggered, so vUE can listen on them directly, like “@tap” etc.

Write plug-in format

A vue plug-in first needs to be an object that contains a key value of install, which corresponds to a function, and takes a vue instance as an argument, like this:

export default {
    install: (app) = > {
        / / logic}};Copy the code

Components also have a life cycle, such as Mounted and unmounted, which represent the element on which the instruction is placed “executed after loading” and “executed on destruction”, respectively.

Here we use these two hooks to perform any-touch initialization and destruction.

Now we begin to wrap the “V-touch” directive. Note: in the code we call the directive “touch”, but when we use it in the component we write “V-touch”. Properties starting with “V -” will be known to vUE as directives.

import ATouch from 'any-touch';
const elAndAtMap = new WeakMap(a);export default {
    install: (app) = > {
        app.directive('touch', {
            mounted(el) {
                / / initialization
                const at = new ATouch(el);
                elAndAtMap.set(el, at);
            },

            unmounted(el: SupportElement) {
                / / destroyelAndAtMap.get(el).destroy(); }}); }};Copy the code

WeakMap is used to store the “any-touch” instance generated each time “V-touch” is used. Write that the feature implementation is complete. But our goal is to write in TS, so keep going.

typescript

First we’ll introduce the types we’ll use to annotate our code.

import type { App, DirectiveBinding } from 'vue';
import type { Options, SupportElement } from 'any-touch';
Copy the code
  1. AppIndicates the vUE instance type.
  2. DirectiveBindingRepresents the parameter type of the instruction. If required on the instructionvalueTo impose constraints, such as restrictionsv-touch=The value of can only be a numberDirectiveBinding<number>.
  3. Optionsisany-touchThe parameter type of.
  4. SupportElementisany-touchThe supported element types are, in effectHTMLElement|SvgElement.

How do I get the value of the instruction

/ / Mounted hook = / mounted hook = / mounted hook = / mounted hook = / mounted hook = / mounted hook = / mounted hook = / mounted hook = / mounted hook = / mounted hook = / mounted hook = / mounted hook =

Since the any-touch argument is the value of the directive, we mark the second argument of type :DirectiveBinding

mounted(el: SupportElement, binding: DirectiveBinding<Options>) {}
Copy the code

The complete code

So let’s label all the types.

import { App, DirectiveBinding } from 'vue';
import type { Options, SupportElement } from 'any-touch';
import ATouch from 'any-touch';
const elAndAtMap = new WeakMap(a);export default {
    install: (app: App) = > {
        app.directive('touch', {
            mounted(el: SupportElement, { value }: DirectiveBinding<Options>) {
                elAndAtMap.set(el, new ATouch(el, value));
            },

            unmounted(el: SupportElement){ elAndAtMap.get(el).destroy(); }}); }};Copy the code

The source address

If you are not familiar with TS, you can take a look at my BASIC TS course.

Getting started with typescript

Lesson one: Play with typescript

Lesson two, basic types and introductory advanced types

Lesson three: Generics

Lesson four: Reading advanced types

Lesson 5: What is a namespace

Special, learn typescript in vue3🔥 source 🦕 – “is”

Lesson 6. What is a declare? 🦕 – Global declaration

Lesson 7: How to use 🦕 module declaration with vue3 example

🍕 Learning interaction

Thank you for your reading. If you have any questions, you can add me to the wechat group, and I will pull you into the wechat group (Because Tencent limits the number of wechat groups to 100, when the number exceeds 100, you must be joined by group members).