shadow icon indicating copy to clipboard operation
shadow copied to clipboard

Shadow dom support for Vue

Shadow

MIT
Shadow dom support for Vue

!!!!!!!!!! important !!!!!!!!!!

For vue2 use 1.x

npm i vue-shadow-dom@1

Usage

  • typescript / node / bundle tools (vite webpack ...)

    npm i vue-shadow-dom
    
    import { createApp } from 'vue'
    import shadow from 'vue-shadow-dom'
    
    const app = createApp(...)
    app.use(shadow)
    app.mount(...)
    
  • importmap

    <head>
      <script type="importmap">
        {
          "imports": {
            "vue": "../path/to/vue.esm-browser.js",
            "vue-shadow-dom": "../path/to/shadow.esm-bundler.mjs"
          }
        }
      </script>
    
      <script type="module">
        import { createApp } from 'vue'
        import shadow from 'vue-shadow-root'
    
        const app = createApp(...)
        app.use(shadow)
        app.mount(...)
      </script>
    </head>
    
  • legacy global

    <head>
      <script src="vue.js"></script>
      <script src="../path/to/shadow.global.js"></script>
    
      <script>
        const app = Vue.createApp(...)
        app.use(shadow)
        app.mount(...)
      </script>
    </head>
    
  • legacy global esm mixed

    <head>
      <script src="vue.js"></script>
      <link rel="modulepreload" href="../path/to/shadow.esm-browser.mjs" />
    
      <script type="module">
        import shadow from '../path/to/shadow.esm-browser.mjs'
    
        const app = Vue.createApp(...)
        app.use(shadow)
        app.mount(...)
      </script>
    </head>
    

Files

  • dist/shadow.global.js
    For UMD
    <script src="vue.js"></script>
    <script src="../path/to/shadow.global.js"></script>
    
  • dist/shadow.esm-browser.mjs | dist/shadow.esm-browser.prod.mjs
    For browser import, when Vue from global
    <script src="vue.js"></script>
    <link rel="modulepreload" href="../path/to/shadow.esm-browser.mjs" />
    <script type="module">
      import shadow from '../path/to/shadow.esm-browser.mjs'
    </script>
    
  • dist/shadow.cdn-jsdelivr.mjs | shadow.cdn-jsdelivr.prod.mjs
    For browser import, when Vue from cdn
    <link rel="modulepreload" href="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.runtime.esm-browser.js" />
    <link rel="modulepreload" href="shadow.cdn-jsdelivr.mjs" />
    <script type="module">
      import shadow from 'shadow.cdn-jsdelivr.mjs'
    </script>
    
  • dist/shadow.esm-bundler.mjs | dist/shadow.esm-bundler.prod.mjs
    For packaging tool or importmap
    import shadow from '../path/to/shadow.esm-bundler.mjs'
    
  • dist/shadow.cjs.cjs | dist/shadow.cjs.prod.cjs
    For node cjs
    const shadow = require('../path/to/shadow.cjs.prod.cjs') 
    
  • shadow.js
    For node cjs
    const shadow = require('vue-shadow-dom') 
    
  • shadow.mjs
    For node esm
    import shadow from 'vue-shadow-dom'
    

<div v-shadow id=app>
  <input>
  <shadow-root>
    <div></div>
    <p>123</p>
  </shadow-root>
</div>

Will output

▼ <div id="app">
 ▼ #shadow-root (open)
    <input>
  ▼ <div>
   ▼ #shadow-root (open)
      <div></div>
      <p>123</p>
    </div>
  </div>

Api

  • <shadow-root>
    Usage:

    <shadow-root></shadow-root>
    

    Props

    • abstract

      • type: boolean
      • default: false

      it change the location of the #shadow-root
      it should not be dynamically changed

      default

      <article>
        <shadow-root><br></shadow-root>
      </article>
      
      ▼ <article>
       ▼ <div>
        ▼ #shadow-root (open)
           <br>
        </article>
      

      abstract

      It will make other external tags unavailable

      <article>
        <shadow-root abstract><br></shadow-root>
      </article>
      
      ▼ <article>
       ▼ #shadow-root (open)
          <br>
        </article>
      
    • tag

      • type: string
      • default: 'div'
      <article>
        <shadow-root tag="section"><br></shadow-root>
      </article>
      
      ▼ <article>
       ▼ <section>
        ▼ #shadow-root (open)
           <br>
         </section>
        </article>
      

    Expose

    const ex = ref<ShadowRootExpose>()
    
    <shadow-root ref="ex"></shadow-root>
    
    • shadow_root

      • type: ShadowRoot
      const shadow_root: ShadowRoot = ex.shadow_root
      
  • shadow-style
    Usage:

    <shadow-style></shadow-style>
    <!-- or -->
    <ShadowRoot.Style></ShadowRoot.Style>
    

    Same to html style

    The reason it exists is that vue SFC disabled style tag

  • ~~v-shadow~~
    Deprecated

    Usage:

    <div v-shadow></div>
    
  • Experimental adoptedStyleSheets

    const adoptedStyleSheets = new CSSStyleSheet()
    adoptedStyleSheets.replace('p { color: green }')
    
    <shadow-root :adopted-style-sheets="[adoptedStyleSheets]">
      <p>test adoptedStyleSheets</p>
    </shadow-root>
    

    result: p is green

Build

npm i
npm run build

Test

npm run test:dev
npm run test:build
npm run test:preview