添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
老实的电梯  ·  Azure Functions – ...·  1 月前    · 
重感情的酸菜鱼  ·  安装libX11过程记录·  1 月前    · 
无邪的弓箭  ·  GitHub - ...·  1 周前    · 
不敢表白的豆浆  ·  查看mysql sql ...·  2 年前    · 

A situation that tends to happen when working on multiple projects is that the same generic components are needed on each individual project like a stylized text field or something a little bit more complex like a date picker.

The best course of action would be to write the component once and update it from a single point, that being the package where it's being distributed from.

What we'll be doing is writing an NPM package that exports a Vue 3 component with TypeScript type definitions to boot! The component I've chosen to make is a tri-state checkbox for this demonstration.

I'll be using Vite for this project since it is a nice alternative to webpack as a build tool and development server. Use your package manager of choice to create a project, I'll go with yarn :

yarn create vite

Choose these settings and name your project ideally how you would name your final component:

√ Project name: ... vue-tri-state-checkbox
√ Select a framework: » Vue
√ Select a variant: » TypeScript
    Enter fullscreen mode
    Exit fullscreen mode

Purge the project of any files or code you don't need, I usually just use App.vue for testing purposes with the components folder being used to store the components and export them.

Your src folder should look like this:

Write your component as you would usually with regards to how Vue 3 works, I am going to use this as an example for my component:

<template>
  <label>
    <input
      type="checkbox"
      :disabled="disabled"
      :indeterminate="val === null"
      :checked="val === true"
      @click="change"
      {{ label }}
    </span>
  </label>
</template>
<script setup lang="ts">
import { ref, watch } from "vue";
const props = withDefaults(
  defineProps<{
    label?: string;
    modelValue: boolean | null;
    disabled?: boolean;
    color?: string;
  }>(),
    color: "#2f4fef"
const emit = defineEmits<{
  (e: "update:modelValue", value: boolean | null): void;
}>();
const val = ref<boolean | null>(false);
const change = () => {
  if (val.value === false) val.value = null;
  else if (val.value === null) val.value = true;
  else val.value = false;
  emit("update:modelValue", val.value);
watch(
  () => props.modelValue,
  (value) => (val.value = value)
</script>
    Enter fullscreen mode
    Exit fullscreen mode

Inside of your src folder we will create an index.ts file which will be used for exporting the component from the components folder.

import TriStateCheckbox from "./components/triStateCheckbox.vue";
export { TriStateCheckbox };
    Enter fullscreen mode
    Exit fullscreen mode

We will need some new dependencies for the next step, so add these packages to your development dependencies which will be explained shortly:

yarn add vite-plugin-dts path -D

The default vite.config.ts you should have at this point resembles this:

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()]
    Enter fullscreen mode
    Exit fullscreen mode
import vue from "@vitejs/plugin-vue";
import * as path from "path";
import { defineConfig } from "vite";
import dts from "vite-plugin-dts";
export default defineConfig({
  plugins: [vue(), dts()],
  build: {
    lib: {
      entry: path.resolve(__dirname, "src/index.ts"),
      name: "TriStateCheckbox",
      fileName: "vue-tri-state-checkbox"
    rollupOptions: {
      external: ["vue"],
      output: {
        globals: {
          vue: "Vue"
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "src")
    Enter fullscreen mode
    Exit fullscreen mode

Let's go over what's going on here: first off, inside the plugins property we added dts which is part of the vite-plugin-dts package. Its main purpose is creating type definition files from vue files automatically for better development experience, that is to say it create d.ts files from .vue ones.

Inside the build property we have defined some additional properties which will be used for defining how the build process of the package itself should work.

lib tells the build process to treat the entire thing like an exportable library, read more here. The properties we define here are:

entry - where the package export is, that is to say where the user will import the package from after publishing it, here we point the entry to the previously defined index.ts folder inside src using the path function and the __dirname variable which points to the main folder of the project name - a unique identifier of the package, try to keep this in line with your package name fileName - a unique identifier which will be used to describe the package file output

Inside rollupOptions we will define a few things to tell Rollup how to configure the module bundler:

external - a definition of any external dependencides needed to run the package, in this case vue itself, read more here output.globals - needed to provide context to the used external dependencies, read more here

Finally, the resolve property is used to make development easier with defining the @ as an alias to the src folder path.

Next we'll be editing the tsconfig.json file:
"compilerOptions": { "target": "ESNext", "useDefineForClassFields": true, "module": "ESNext", "moduleResolution": "Node", "strict": true, "jsx": "preserve", "resolveJsonModule": true, "isolatedModules": true, "esModuleInterop": true, "lib": ["ESNext", "DOM"], "skipLibCheck": true, "noEmit": true "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], "references": [{ "path": "./tsconfig.node.json" }] Enter fullscreen mode Exit fullscreen mode

When you're all done editing the previously mentioned files, we need to see if the build process works by running yarn build.

You should get an output similar to this:

$ vue-tsc && vite build
vite v4.3.9 building for production...
✓ 4 modules transformed.
dist/style.css              2.15 kB │ gzip: 0.65 kB
dist/vue-tri-state-checkbox.js  1.12 kB │ gzip: 0.58 kB
dist/vue-tri-state-checkbox.umd.cjs  1.09 kB │ gzip: 0.61 kB
[vite:dts] Start generate declaration files...
✓ built in 1.29s
[vite:dts] Declaration files built in 822ms.
Done in 3.49s.
    Enter fullscreen mode
    Exit fullscreen mode
style.css - the CSS of the package bundled inside a singular entry point
vue-tri-state-checkbox.js - main package entry point which contains the bundled JavaScript code
vue-tri-state-checkbox.umd.cjs - universal module system and common js entry point
index.d.ts - generated type definitions

All of these are located inside the dist folder which will be used to distribute the package with NPM.

Before we do that though, we have to edit package.json.

package.json

We will need to alter package.json in order to distribute the newly created component (the words component and package will be used interchangeably from now on):

private needs to be set to false
  • add a files property to specify which files will play a role in how the package functions, after building the component with yarn build all of the distribution files will be inside the dist folder
    "files": ["dist", "src/components/"],
        Enter fullscreen mode
        Exit fullscreen mode
    

    Additionally, we will be adding the src/components folder because the components are exported from there.

  • name your GIT repository inside the repository property
    "repository": {
      "type": "git",
      "url": "git+https://github.com/MatijaNovosel/tri-state-checkbox.git"
        Enter fullscreen mode
        Exit fullscreen mode
      ".": {
        "import": "./dist/vue-tri-state-checkbox.js",
        "require": "./dist/vue-tri-state-checkbox.umd.cjs"
      "./dist/style.css": {
        "import": "./dist/style.css",
        "require": "./dist/style.css"
        Enter fullscreen mode
        Exit fullscreen mode
      "repository": {
        "type": "git",
        "url": "git+https://github.com/MatijaNovosel/tri-state-checkbox.git"
      "keywords": [
        "checkbox",
        "vue-tri-state-checkbox",
        "material",
        "material-ui",
        "vue3",
        "vue",
        "vuejs"
      "files": ["dist", "src/components/"],
      "main": "./dist/vue-tri-state-checkbox.umd.cjs",
      "module": "./dist/vue-tri-state-checkbox.js",
      "exports": {
        ".": {
          "import": "./dist/vue-tri-state-checkbox.js",
          "require": "./dist/vue-tri-state-checkbox.umd.cjs"
        "./dist/style.css": {
          "import": "./dist/style.css",
          "require": "./dist/style.css"
      "types": "./dist/index.d.ts",
      "scripts": {
        "dev": "vite",
        "build": "vue-tsc && vite build",
        "preview": "vite preview"
      "dependencies": {
        "sass": "^1.62.1",
        "vue": "^3.2.47"
      "peerDependencies": {
        "vue": "^3.0.0"
      "devDependencies": {
        "@vitejs/plugin-vue": "^4.1.0",
        "path": "^0.12.7",
        "typescript": "^5.0.2",
        "vite": "^4.3.9",
        "vite-plugin-dts": "^2.3.0",
        "vue-tsc": "^1.4.2"
        Enter fullscreen mode
        Exit fullscreen mode
    

    First you will need to log in with npm login, complete the process then run npm publish.

    If everything goes to plan you should see this prop up in your output:

    npm notice Publishing to https://registry.npmjs.org/
    + [email protected]
        Enter fullscreen mode
        Exit fullscreen mode
    

    Inside of your new project you should be able to install it using your package manager of choice: yarn add vue-tri-state-checkbox.

    To use the component, define it globally or just import it locally like this, including the CSS file:

    <template>
      <tri-state-checkbox v-model="val" />
    </template>
    <script lang="ts" setup>
    import { ref } from "vue";
    import { TriStateCheckbox} from "vue-tri-state-checkbox";
    import "vue-tri-state-checkbox/dist/style.css";
    const val = ref(null);
    </script>
        Enter fullscreen mode
        Exit fullscreen mode
    

    Even though it is a bit tedious, making exportable components for your projects can be a time saver and very practical.

    The source code for this project can be found here:

    Vue tri state checkbox

    A material tri state checkbox component for Vue 3. Part of my component export tutorial.

    🚀 Installation

    Install using your package manager of choice:

    yarn add vue-tri-state-checkbox
    Enter fullscreen mode Exit fullscreen mode <script lang="ts" setup> import { ref } from "vue"; import { TriStateCheckbox } from "vue-tri-state-checkbox"; import "vue-tri-state-checkbox/dist/style.css"; const val = ref(null); </script>
    Enter fullscreen mode Exit fullscreen mode Modular and scalable Front End architecture 🗃️ Experienced 💻 Javascript Developer Master & Vue.js Lover 💘 Vue Consultant 👨‍🏫 Modular and scalable Front End architecture 🗃️ Experienced 💻 Javascript Developer Master & Vue.js Lover 💘 Vue Consultant 👨‍🏫 Once unpublished, all posts by matijanovosel will become hidden and only accessible to themselves. If matijanovosel is not suspended, they can still re-publish their posts from their dashboard.

  •