0.0.6 • Published 2 years ago

@8bu/use-mounting v0.0.6

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

@8bu/use-mounting

Programmatic mount your Vue component

npm version npm license bundle size npm

Background

I want to clone the programmatic modal of Buefy. So I created this thing. You can use it in the same situation like programmatic modal of Buefy does:

  • Open your modal/dialog by function, with custom template/component
  • Push new notification/snackbar by function, with custom template

Usage

Install

# NPM
npm i @8bu/use-mounting
# PNPM
pnpm i @8bu/use-mounting
# YARN
yarn add @8bu/use-mounting

Config main.ts

import { MountingPlugin } from '@8bu/use-mounting'

// provide mounting instance to lower level components
app.use(MountingPlugin());

Quick start

Hehe.vue

<script>
export default defineComponent({
  name: 'Hehe',
  props: {
    msg: {
      type: String,
      required: true,
    },
  },
})
</script>

<template>
  <div class="border w-64 mx-auto p-4">
    Hehe
    <p>
      {{ msg }}
    </p>
    <hr>
    <slot />
  </div>
</template>

Hihi.vue

<script>
export default defineComponent({
  name: 'Hihi',
  props: {
    msg: {
      type: String,
      required: true,
    },
  },
})
</script>

<template>
  <div class="border border-yellow-500 w-52 my-4 mx-auto p-4">
    Hihi
    <p>
      {{ msg }}
    </p>
  </div>
</template>

App.vue

<script setup>
import { onUnmounted, ref } from 'vue'
import { useMounting } from '@8bu/use-mounting'

const { mount } = useMounting()

const counter = ref(1)
const programmatic = ref()
let destroyComp = null

onUnmounted(() => destroyComp?.())

const insert = async() => {
  destroyComp?.()
  destroyComp = mount({
    el: (await import('~/components/Hehe.vue')).default,
    props: {
      key: counter,
      msg: `Message ${counter.value++}`,
    },
    parent: programmatic.value,
    elContent: [
      {
        el: (await import('~/components/Hihi.vue')).default,
        props: {
          key: counter,
          msg: `Message ${counter.value + 50}`,
        },
      },
    ],
  })
}
</script>
<template>
  <div class="p-4">
    <div ref="programmatic" class="border border-orange-500 my-4 p-10">
      <span class="mb-4 font-mono">
        ref="programmatic"
      </span>
    </div>
    <button class="rounded-lg px-4 py-1 bg-white text-blue-400" @click="insert">
      Insert component
    </button>
  </div>
</template>

Config

Hook

import { useMounting } from '@8bu/use-mounting'
const { mount } = useMounting()

const destroyMounted = mount(config)

// Execute to destroy the mounted component
destroyMounted()

Hook config

The interface

interface MountFnConfig {
  el: Component
  props?: (VNodeProps & Record<string, any>) | Ref<VNodeProps & Record<string, any>>
  elContent?: ChildFnConfig[]
  parent?: Component
}
export type ChildFnConfig = Exclude<MountFnConfig, 'parent'>

Config object cheatsheet

KeyDescriptionTypeRequiredDefault value
elComponent that you want to mountVue ComponentYes-
propsPassing props to el component, use ref() if your props is gonna changeObject | RefNo-
parentPlace to mount your componentTemplate RefNoRoot container (App)
elContentArray - Same as hook config, but without parentMountFnConfig[]No-

License

MIT License © 2022 8bu

0.0.6

2 years ago

0.0.5

2 years ago

0.0.4

2 years ago

0.0.3

2 years ago

0.0.2

2 years ago

0.0.1

2 years ago

0.0.1-beta.2

2 years ago

0.0.1-beta.1

2 years ago