ワイズリマインダー

CDN版Vue3で孫SFCから親の変数をリアクティブに読み込んでみた

デモ表示はこちら

次の条件のもと作成されています。
・Vue3その他もろもろはインストールしたくない。
・CDNからダウンロードした各種jsを同ドメイン内にアップロードしている。
・CompositionAPIを使用。

 

【ポイント】
インストール版ではないのでprovide(),inject()はVue.provide(),Vue.inject()と記述する。

 

index.html

<div id="app">
 <compo-child></compo-child>
</div>

 

index.js

'use strict';
(function($){
  $(document).ready(function(){
    Vue.createApp({
      setup( ){
        const hoge = Vue.ref('hage');
        Vue.provide('hoge', hoge);
      }
     ,components: {
        'compo-child': Vue.defineAsyncComponent( () => window['loadModule']('child.vue', window['loaderOption']() ) )
      }
    }).mount('#app');
  });
  
  window['loadModule'] = window['vue3-sfc-loader']['loadModule'];
  window['loaderOption'] = function(){
    return{
      moduleCache: { vue: Vue }
     ,getFile(url){
        url = /.*?\.js|.mjs|.css|.less|.vue$/.test(url) ? url : `${url}.vue`;
        url += "?" + Math.random();
        const type = /.*?\.js|.mjs$/.test(url) ? ".mjs" : /.*?\.vue$/.test(url) ? ".vue" : /.*?\.css$/.test(url) ? ".css" : ".vue";
        const getContentData = (asBinary) => fetch(url).then((res) => !res.ok ? Promise.reject(url) : asBinary ? res.arrayBuffer() : res.text() );
        return { getContentData: getContentData, type: type };
      }
     ,addStyle(textContent) {
        let styleElement = document.createElement("style");
        document.head.insertBefore(
          Object.assign(styleElement, { textContent })
         ,document.head.getElementsByTagName("style")[0] || null
        );
      }
     ,handleModule(type, getContentData, path, options) {
        switch (type) {
          case ".css":
            return options.addStyle(getContentData(false));
          case ".less":
            console.error(".......");
        }
      }
     ,log(type, ...args) { console.log(type, ...args); }
    }
  };

})(jQuery);

 

child.vue

<template>
 <div>Children</div>
 <grand-child></grand-child>
</template>
<script scoped>
export default{
  setup(){
  }
 ,components: {
    'grand-child': Vue.defineAsyncComponent( () => window['loadModule']('grand_child.vue', window['loaderOption']() ) )
  }
}
</script>

 

grand_child.vue

<template>
 <div>Grand Children</div>
 <button type="button" @click="GCB">GCbutton</button>
</template>
<script scoped>
export default{
  setup( ){
    const hoge = Vue.inject('hoge');
    const GCB = ( e ) => {
      console.log([ hoge.value ]);
    };
    
    return {
      GCB
    };
  }
}
</script>

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

検索

最近のコメント

最近の投稿

タグ

フィード配信

アーカイブ

外部リンク