簡體   English   中英

在vue.js中使用動態組件

[英]Working with dynamic components in vue.js

我有一個簡單的應用程序,需要動態渲染2個組件。

  • 組件A-需要具有onClick事件。
  • 組件B-需要具有onChange事件。

如何將不同事件動態附加到組件A / B?

<template>
  <component v-bind:is="currentView">
  </component>
</template>

<script>
import A from '../components/a.vue'
import B from '../components/b.vue'

export default {
  data: function () {
    return {
      currentView: A
    }
  },
  components: { A, B }
}
</script>

這是一個更為復雜和實際的用例的解決方案。 在這種情況下,您必須使用v-for渲染多個不同的組件。

父組件將一組組件傳遞給create-components create-components將在此數組上使用v-for,並顯示所有具有正確事件的組件。

我正在使用自定義指令custom-events來實現此行為。

parent

<template>
    <div class="parent">
        <create-components :components="components"></create-components>
    </div>
</template>

<script>
import CreateComponents from '@/components/CreateComponents'
import ComponentA from '@/components/ComponentA'
import ComponentB from '@/components/ComponentB'

export default {
    name: 'parent',
    data() {
        return {
            components: [
                {
                    is: ComponentA,
                    events: {
                        "change":this.componentA_onChange.bind(this)
                    }
                },
                {
                    is: ComponentB,
                    events: {
                        "click":this.componentB_onClick.bind(this)
                    }
                }
            ]
        }
    },
    methods: {
        componentA_onChange() {
            alert('componentA_onChange');
        },
        componentB_onClick() {
            alert('componentB_onClick');
        }
    },
    components: { CreateComponents }
};
</script>

create-components

<template>
    <div class="create-components">
        <div v-for="(component, componentIndex) in components">
            <component v-bind:is="component.is" v-custom-events="component.events"></component>
        </div>
    </div>
</template>

<script>
export default {
    name: 'create-components',
    props: {
        components: {
            type: Array
        }
    },
    directives: {
        CustomEvents: {
            bind: function (el, binding, vnode) {
                let allEvents = binding.value;
                if(typeof allEvents !== "undefined"){
                    let allEventsName = Object.keys(binding.value);
                    allEventsName.forEach(function(event) {
                        vnode.componentInstance.$on(event, (eventData) => {
                            allEvents[event](eventData);
                        });
                    });
                }
            },
            unbind: function (el, binding, vnode) {
                vnode.componentInstance.$off();
            }
        }
    }
  }
</script>

您不必動態添加它們。

<component v-bind:is="currentView" @click="onClick" @change="onChange">

如果要小心,可以在currentView的處理程序中保釋不正確。

methods: {
  onClick(){
    if (this.currentView != A) return
    // handle click
  },
  onChange(){
    if (this.currentView != B) return
    // handle change
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM