ワイズリマインダー

CDN版Vue3で兄弟SFCのメソッドを親経由で実行してみた

デモ表示はこちら

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

 

【ポイント】
Storeを使用しない。(別ライブラリが必要なため)

 

index.html

<div id="app">
 <child-a ref="childRefA"></child-a>
 <child-b ref="childRefB"></child-b>
</div>

 

index.js

'use strict';
(function($){
  $(document).ready(function(){
    Vue.createApp({
      setup( ){
        const childRefA = Vue.ref(null);        
        const provA = ( arg ) => {
          console.log([ 'provA', arg ]);
          childRefA.value.alertA( arg );
        };
        Vue.provide('provA', provA);

        const childRefB = Vue.ref(null);
        const provB = ( arg ) => {
          console.log([ 'provB', arg ]);
          childRefB.value.alertB( arg );
        };
        Vue.provide('provB', provB);
        
        return {
          childRefA
         ,childRefB
        };
      }
     ,components: {
        'child-a': Vue.defineAsyncComponent( () => window['loadModule']('childA.vue', window['loaderOption']() ) )
       ,'child-b': Vue.defineAsyncComponent( () => window['loadModule']('childB.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);

 

childA.vue

<template>
 <div>ChildrenA</div>
 <button type="button" @click="clickA">Aボタン</button>
</template>
<script scoped>
export default{
  setup(){
    const injectB = Vue.inject('provB');
    const clickA = ( e ) => {
      console.log([ 'clickA', e ]);
      injectB( e );
    };
    const alertA = ( arg ) => {
      console.log([ 'alertB', arg ]);
      alert( arg.target.innerText + "がクリックされました\nchildAで表示しています。");
    };
    return {
      clickA
     ,alertA
    };
  }
}
</script>

 

childB.vue

<template>
 <div>ChildrenB</div>
 <button type="button" @click="clickB">Bボタン</button>
</template><script scoped>
export default{
  setup(){
    const injectA = Vue.inject('provA');
    const clickB = ( e ) => {
      console.log([ 'clickB', e ]);
      injectA( e );
    };

    const alertB = ( arg ) => {
      console.log([ 'alertB', arg ]);
      alert( arg.target.innerText + "がクリックされました\nchildBで表示しています。");
    };
    return {
      clickB
     ,alertB
    };
  }
}
</script>

コメントを残す

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

CAPTCHA


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

検索

最近のコメント

最近の投稿

タグ

フィード配信

アーカイブ

外部リンク