Vue.js: check if a component exists

前端 未结 6 1268
天命终不由人
天命终不由人 2021-02-12 13:26

I need to do some stuff in the ready: of the root instance only when some components don\'t exist (they weren\'t declared in the HTML).

How can I check if a

相关标签:
6条回答
  • 2021-02-12 13:43

    We can get the list of the loaded (global and/or local) components of a Vue instance from the instantiation options which is available through the vm.$options where the vm is the current Vue instance.

    vm.$options property holds the whole options of a Vue instance. For example vm.$options.components returns an object containing the loaded components of the current Vue instace vm.

    However depending on the way how a component is registered, either globally through Vue.component() or locally within a Vue instance options, the structure of the vm.$options.components would be different.

    If the component is registered globally, the component will be added to vm.$options.components [[Prototype]] linkage or its __proto__.

    And if the component is registered locally within the Vue instance options, the component will be added to the vm.$options.components object directly as its own property. So that we do not have to walk the proto chain to find the component.


    In the following example we will see how to access the loaded components in both situations.

    Notice the // [1] and // [2] comments in the code which are related to local registered components.

    // the globally registered component
    Vue.component('global-child', {
      template: '<h2>A message from the global component</h2>'
    });
    
    var localComponent = Vue.extend({ template: '<h2>A message from the local component</h2>' });
    
    
    // the root view model
    new Vue({
      el: 'body',
      data: {
        allComponents: [],
        localComponents: [],
        globalComponentIsLoaded: false
      },
      // local registered components
      components: { // [1]
        'local-child': localComponent
      },
      ready: function() {    
        this.localComponents = Object.keys(this.$options.components); // [2]
        
        this.allComponents = loadedComponents.call(this);
        this.globalComponentIsLoaded = componentExists.call(this, 'global-child');
      }
    });
    
    function loadedComponents() {
      var loaded = [];
      var components = this.$options.components;
      for (var key in components) {
        loaded.push(key);
      }
      return loaded;
    }
    
    function componentExists(component) {
      var components = loadedComponents.call(this);
      if (components.indexOf(component) !== -1) {
        return true;
      }
      return false;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.24/vue.js"></script>
    <h1>A message from the root Vue instance</h1>
    <p>All loaded components are: {{ allComponents | json }}</p>
    <p>local components are: {{ localComponents | json }}</p>
    <p><code>&lt;global-child&gt;</code> component is loaded: <strong>{{ globalComponentIsLoaded }}</strong></p>
    <global-child></global-child>
    <local-child></local-child>

    0 讨论(0)
  • 2021-02-12 13:51

    I'm not sure if you need a dynamic method, but this may help to determine if a component exists:

    Vue.options.components['CompOne']
    

    found:

    https://github.com/vuejs/Discussion/issues/140

    0 讨论(0)
  • 2021-02-12 14:00
    var isComponentExists = "component-name" in Vue.options.components
    
    0 讨论(0)
  • I really hope there is a better answer than this, but for the moment this solves the problem.

    In the ready, I access the children elements through this (could be also Vue) and check whether their name is or not what I was expecting:

        ready: function() {
    
            for (var i = 0; i < this.$children.length; i++) {
                if (
                       this.$children[i].$options.name == 'my_component_a'
                    || this.$children[i].$options.name == 'my_component_b'
                    || this.$children[i].$options.name == 'my_component_c'
                ) {
                    //do stuff
                }
            }
        }
    

    You can also access them directly if you previously assigned them a reference in their template: //template:

    <comp v-ref:my_component_ref></comp>
    

    Then from the Vue component ready:

    if (this.$refs.my_component_ref){
    //do stuff
    }
    
    0 讨论(0)
  • 2021-02-12 14:01

    To check if a global component exists:

    let componentExists = 'componentName' in Vue.options.components
    

    To check if a imported component exists in a component:

    let componentExists = 'componentName' in this.$options.components
    
    0 讨论(0)
  • 2021-02-12 14:06

    get the current component imported components

    this.$options.components[findComponentName]
    

    get the global components

    Vue.$options.components[findComponentName]
    
    0 讨论(0)
提交回复
热议问题