DOM元素到相应的vue.js组件

时间:2014-11-13 17:50:01

标签: javascript dom vue.js

如何找到与DOM元素对应的vue.js组件?

如果我有

element = document.getElementById(id);

是否存在与jQuery等效的vue方法 $(element)

12 个答案:

答案 0 :(得分:41)

正确的方法是使用v-el指令为其提供参考。然后你可以this.$$[reference]

更新vue 2

在Vue 2中,refs用于元素和组件:http://vuejs.org/guide/migration.html#v-el-and-v-ref-replaced

答案 1 :(得分:34)

就这个(在“方法”中的方法):

element = this.$el;

:)

答案 2 :(得分:14)

在Vue.js中,在Vue实例内部组件:

  • 使用this.$el获取实例/组件已挂载到
  • 的HTMLElement

来自 HTMLElement

  • 使用HTMLElement中的.__vue__
    • E.g。 var vueInstance = document.getElementById('app').__vue__;

在名为VNode的变量中加vnode,您可以:

  • 使用vnode.elm获取VNode呈现为
  • 的元素
  • 使用vnode.context获取VNode所支持的Vue实例
  • 使用vnode.componentInstance获取VNode所关注的组件实例

来源,字面意思:vue/flow/vnode.js

Runnable Demo:

Vue.component('my-component', {
  template: `<input>`,
  mounted: function() {
    console.log('[my-component] is mounted at element:', this.$el);
  }
});

Vue.directive('customdirective', {
  bind: function (el, binding, vnode) {
    console.log('My Element is:', vnode.elm);
    console.log('My componentInstance is:', vnode.componentInstance);
    console.log('My Vue Instance is:', vnode.context);
  }
})

new Vue({
  el: '#app',
  mounted: function() {
    console.log('This Vue instance is mounted at element:', this.$el);
    
    console.log('From the element to the Vue instance:', document.getElementById('app').__vue__);
    console.log('Vue component instance of my-component:', document.querySelector('input').__vue__);
  }
})
<script src="https://unpkg.com/vue@2.5.15/dist/vue.min.js"></script>

<h1>Open the browser's console</h1>
<div id="app">
  <my-component v-customdirective=""></my-component>
</div>

答案 3 :(得分:10)

如果您从DOM元素开始,请检查该元素的__vue__属性。任何Vue视图模型(组件,由v-repeat用法创建的VM)都将具有此属性。

您可以在浏览器开发者控制台(至少在Firefox和Chrome中)中使用“检查元素”功能来查看DOM属性。

希望有所帮助!

答案 4 :(得分:4)

由于v-ref不再是指令,而是特殊属性,因此也可以动态定义。这与v-for结合使用时特别有用。

例如:

<ul>
    <li v-for="(item, key) in items" v-on:click="play(item,$event)">
        <a v-bind:ref="'key' + item.id" v-bind:href="item.url">
            <!-- content -->
        </a>
    </li>
</ul>

并在Vue组件中,您可以使用

var recordingModel = new Vue({
  el:'#rec-container',
  data:{
    items:[]
  },

  methods:{
    play:function(key,e){
      // it contains the bound reference
      console.log(this.$refs['item'+key]);
    }
  }
});

答案 5 :(得分:3)

所以我认为$0.__vue__与HOC(高阶组件)的效果不佳。

// ListItem.vue
<template>
    <vm-product-item/>
<template>

从上面的模板中,如果您有ListItem组件,其中ProductItem为根,并且您在控制台中尝试$0.__vue__,则结果会出乎意料ListItem实例。

在这里,我得到了一个解决方案来选择最低级别的组件(在这种情况下为ProductItem)。

插件

// DomNodeToComponent.js
export default {
  install: (Vue, options) => {
    Vue.mixin({
      mounted () {
        this.$el.__vueComponent__ = this
      },
    })
  },
}

安装

import DomNodeToComponent from'./plugins/DomNodeToComponent/DomNodeToComponent'
Vue.use(DomNodeToComponent)

使用

  • 在浏览器控制台中,点击dom元素。
  • 输入$0.__vueComponent__
  • 用组件做任何你想做的事。访问数据。做改变。从e2e运行公开的方法。

奖金功能

如果您想要更多,可以使用$0.__vue__.$parent。意味着如果3个组件共享同一个dom节点,则必须编写$0.__vue__.$parent.$parent来获取主要组件。这种方法不那么简洁,但可以提供更好的控制。

答案 6 :(得分:0)

我找到了这段代码here。这个想法是提升DOM节点层次结构,直到找到__vue__属性。

function getVueFromElement(el) {
  while (el) {
    if (el.__vue__) {
      return el.__vue__
    } else {
      el = el.parentNode
    }
  }
}

在Chrome中:

Usage in Chrome

答案 7 :(得分:0)

  • this.$el-指向组件的根元素
  • this.$refs.<ref name> + <div ref="<ref name>" ...-指向嵌套元素
  

?仅在vue lifecycle$el步骤之后才使用$refs / mounted()

<template>
    <div>
        root element
        <div ref="childElement">child element</div>
    </div>
</template>

<script>
    export default {
        mounted() {
            let rootElement = this.$el;
            let childElement = this.$refs.childElement;

            console.log(rootElement);
            console.log(childElement);
        }
    }
</script>

<style scoped>
</style>
  

enter image description here

答案 8 :(得分:0)

Vue 3 的解决方案

我需要创建一个导航栏并在外部单击时折叠菜单项。我在 mounted 生命周期挂钩中的 windows 上创建了一个点击侦听器,如下所示

mounted() {
    window.addEventListener('click', (e)=>{
        if(e.target !== this.$el)
            this.showChild = false;
    })
}

您还可以检查该元素是否是 this.$el 的子元素。然而,在我的情况下,孩子们都是链接,这并不重要。

答案 9 :(得分:-1)

如果你想用&#34; demo&#34;在输入上听一个事件(即OnClick)。 id,你可以使用:

new Vue({
  el: '#demo',
  data: {
    n: 0
  },
  methods: {
   onClick: function (e) {
     console.log(e.target.tagName) // "A"
     console.log(e.targetVM === this) // true
  }
 }
})

答案 10 :(得分:-4)

恰恰是卡米尔所说的,

element = this.$el

但请确保您没有fragment instances

答案 11 :(得分:-4)

由于在Vue 2.0中,似乎没有可用的解决方案,我找到的一个干净的解决方案是创建vue-id属性,并在模板上设置它。然后在createdbeforeDestroy生命周期中,这些实例将在全局对象上更新。

基本上:

created: function() {
    this._id = generateUid();
    globalRepo[this._id] = this;
},

beforeDestroy: function() {
    delete globalRepo[this._id]
},

data: function() {
    return {
        vueId: this._id
    }
}