【问题标题】:Vue.js: check if a component existsVue.js:检查组件是否存在
【发布时间】:2016-05-23 11:28:01
【问题描述】:

只有当某些组件不存在(它们没有在 HTML 中声明)时,我才需要在根实例的 ready: 中做一些事情。

如何检查组件是否存在?

【问题讨论】:

  • 试试v-ref, vuejs.org/api/#v-ref, <comp v-ref:comp-name></comp>, if (this.$refs.compName)..

标签: javascript vue.js


【解决方案1】:

我们可以从vm.$options 提供的实例化选项中获取已加载(全局和/或本地)的 Vue 实例组件列表,其中vm 是当前的 Vue 实例。

vm.$options 属性包含 Vue 实例的全部选项。例如 vm.$options.components 返回一个对象,其中包含当前 Vue 实例 vm 的已加载组件。

但是,根据组件的注册方式,通过Vue.component()locally within a Vue instance options 全局注册,vm.$options.components 的结构会有所不同。

如果组件是全局注册的,该组件将被添加到vm.$options.components [[Prototype]] 链接或其__proto__

如果组件在 Vue 实例选项中本地注册,该组件将作为自己的属性直接添加到 vm.$options.components 对象中。这样我们就不必遍历 proto 链来查找组件。


在下面的示例中,我们将看到如何在两种情况下访问加载的组件。

注意代码中与本地注册组件相关的// [1]// [2] cmets。

// 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>

【讨论】:

  • 我真的很感谢你的解释,不幸的是不适合我。我想知道 HTML 中使用的组件。如果我删除了 HTML 中的 元素,我做了一点小改动,但它仍然被识别为已加载:jsfiddle.net/ncmqhy5n/2
【解决方案2】:

检查全局组件是否存在:

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

检查组件中是否存在导入的组件:

let componentExists = 'componentName' in this.$options.components

【讨论】:

    【解决方案3】:

    我不确定您是否需要动态方法,但这可能有助于确定组件是否存在:

    Vue.options.components['CompOne']
    

    找到:

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

    【讨论】:

      【解决方案4】:

      获取当前组件导入的组件

      this.$options.components[findComponentName]
      

      获取全局组件

      Vue.$options.components[findComponentName]
      

      【讨论】:

      【解决方案5】:

      我真的希望有比这更好的答案,但目前这解决了问题。

      在准备好的时候,我通过this(也可以是Vue)访问子元素并检查他们的名字是否是我所期望的:

          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
                  }
              }
          }
      

      如果您之前在其模板中为其分配了引用,您也可以直接访问它们: //模板:

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

      然后从Vue组件准备好:

      if (this.$refs.my_component_ref){
      //do stuff
      }
      

      【讨论】:

        【解决方案6】:
        var isComponentExists = "component-name" in Vue.options.components
        

        【讨论】:

        • 这并没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方留下评论。 - From Review
        • @VinayPrajapati 似乎是一个合法的答案
        • 请解释一下 OP 做错了什么以及它如何解决问题。应避免使用一种衬里。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-10-26
        • 2021-12-22
        • 1970-01-01
        • 1970-01-01
        • 2020-06-07
        • 1970-01-01
        • 2011-06-20
        相关资源
        最近更新 更多