Vue3 encapsulates custom instructions and hooks, and publishes npm packages

Requirements: Encapsulate a function that requires monitoring the width and height changes of the DOM, and supports both custom instructions and hooks.

Step 1: Create the project folder v-resize-xm

1. Create the src folder in the v-resize-xm folder

Execute the pnpm init command to generate a package.json file

2. Install ts

sudo npm install -g typescript

3. Execute tsc –init to generate a tsconfig.json file

4. Create a new vite.config.ts file in the v-resize-xm folder

5. Create a new index.d.ts declaration file in the v-resize-xm folder

6. To install vue, execute pnpm install [email protected] -D (because the user who ultimately uses this plug-in has vue locally)

7. To install vite, execute pnpm install [email protected] -D (Because the user who will eventually use this plug-in has vite locally)

Write v-resize-xm\src\index.ts business file

import type { App } from 'vue';
// Listen for changes in element width and height
//Hooks
function useResize (el:HTMLElement, callback:Function) {
    let resize = new ResizeObserver((entries) => {
        // entries is an array, by default it listens to multiple
        callback(entries[0].contentRect); // Return the box height back
    })
    resize.observe(el)
}

let app = createApp(); // Create an app

//The vue plug-in is used as follows:
// app.use(router).use(xxx); // etc.
// This use actually calls the underlying install method.
// The vue plug-in is to implement the install function. It calls it and injects the app into it. Its type is the App introduced in vue.

//Custom instructions
const install = (app:App) => { // Finally provide an install method for app
    // After getting this app, you can create directives
    app.directive('resize', {
        // The first parameter is the html element, and the second parameter is the binding object. This object can require it to be passed in a function.
        mounted(el, binding) {
            // Just reuse useResize
            // Mounting of instructions
            useResize(el, binding.value);
        }
    })
}
//Register install to the function
useResize.install = install;

export default useResize;

Step 2: Configure some packaged libraries in vite.config.ts

import { defineConfig } from 'vite';
// umd supports amd cmd cjs global variable mode
export default defineConfig({
    // Develop vue3 library mode document https://cn.vitejs.dev/guide/build.html#library-mode
    build:{
        lib:{
            entry:'./src/index.ts', // Entry
            name: 'useResize' // Just have the same name as the hooks name
        },
        //Transparently pass some attributes to rollup
        rollupOptions:{
            // Because this is a vue plug-in, the user already has a Vue environment locally, so there is no need to include Vue in the package here.
            external:['vue'],
            output:{
                globals:{
                    useResize: 'useResize' // Provide a global variable for the umd library to use
                }
            }
        }
    }
})

Step 3: Configure some commands in package.json

“build”: “vite build”

{
  "name": "v-resize-xm",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo "Error: no test specified" & amp; & amp; exit 1",
    "build": "vite build"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "vue": "3.2.47"
  }
}

Execute npm run build to build the dist package

We see two files typed out in the dist directory

v-resize-xm.mjs ES mode

v-resize-xm.umd.js other modes

Step 4: Write the ts declaration file index.d.ts

declare const useResize: {
    (el: HTMLElement, callback: Function): void;
    install: (app: App) => void;
};

export default useResize;

Step 5: Publish npm package

1. Configure the main attribute of package.json. This main is generally the directory corresponding to require

“main”: “dist/v-resize-xm.umd.js”, umd it supports commonJs specification

2. Configure the module attribute of package.json. This module supports the import introduction of ES6

“module”: “dist/v-resize-xm.mjs”,

3. Configure the files array attribute of package.json

This indicates the directory sent to npm. We will send the dist directory and declaration file.

“files”: [ “dist”, “index.d.ts”],

4. Corrected version number

“version”: “1.0.1”,

{
  "name": "v-resize-xm",
  "version": "1.0.0",
  "description": "",
  "main": "dist/v-resize-xm.umd.js",
  "module": "dist/v-resize-xm.mjs",
  "scripts": {
    "test": "echo "Error: no test specified" & amp; & amp; exit 1",
    "build": "vite build"
  },
  "keywords": [],
  "author": "",
  "files": [ "dist", "index.d.ts"],
  "license": "ISC",
  "devDependencies": {
    "vue": "3.2.47"
  }
}

5. Register npm account

npm registration address

6. Execute npm adduser command to add npm account

7. Execute the npm login command to log in

8. Execute npm publish command to publish

9. Go to npm official website to search and view

Step 6: Test using the published library

1. Execute pnpm install library name -S in the vue3 project environment

Hooks usage

<template>
  <div id="resize">
    <img id="img" width="300" height="300" src="./assets/1.png">
  </div>
</template>
<script setup lang="ts">
import userResize from 'v-resize-xm';
import { onMounted } from 'vue';
// Because this is to operate the DOM, we have to wait for the page rendering to complete and operate in the onMounted life cycle.
onMounted(() => {
  userResize(document.querySelector('#resize') as HTMLElement,
    (e: any) => {
      console.log(e) // Get the changes in element length and width
    }
  )
})
</script>
<style scoped>
#resize {
  border: 1px solid #ccc;
  resize: both;
  overflow: hidden;
}
</style>

Custom instruction usage

Introduce and register instructions in main.ts

import './assets/main.css'

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
import router from './router'

import useResize from 'v-resize-xm'; // 1. Introduce the command plug-in we released

const app = createApp(App)

app.use(createPinia())
app.use(router)
app.use(useResize) // 2. Registration command
app.mount('#app')

Use the v-resize=”drag” directive and callback function in the page

<template>
  <div v-resize="drag" id="resize">
    <img id="img" width="300" height="300" src="./assets/1.png">
  </div>
</template>
<script setup lang="ts">
// import userResize from 'v-resize-xm';
import { onMounted } from 'vue';
const drag = (e: any) => {
  console.log(e) // Get the changes in element length and width
}
</script>
<style scoped>
#resize {
  border: 1px solid #ccc;
  resize: both;
  overflow: hidden;
}
</style>

The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge. Vue entry skill treeNode.js and npmNode installation and configuration 39858 people are learning the system