【发布时间】:2015-01-10 23:18:12
【问题描述】:
如何找到一个DOM元素对应的vue.js组件?
如果我有
element = document.getElementById(id);
有没有相当于jQuery的vue方法
$(element)
【问题讨论】:
-
据我所知,没有办法做到这一点。
-
你介意接受我的回答吗?
标签: javascript dom vue.js
如何找到一个DOM元素对应的vue.js组件?
如果我有
element = document.getElementById(id);
有没有相当于jQuery的vue方法
$(element)
【问题讨论】:
标签: javascript dom vue.js
如果您想在带有“演示”ID 的输入上监听事件(即 OnClick),您可以使用:
new Vue({
el: '#demo',
data: {
n: 0
},
methods: {
onClick: function (e) {
console.log(e.target.tagName) // "A"
console.log(e.targetVM === this) // true
}
}
})
【讨论】:
正确的做法是使用v-el 指令给它一个参考。那你就可以this.$$[reference]了。
在 Vue 2 中,元素和组件都使用引用:http://vuejs.org/guide/migration.html#v-el-and-v-ref-replaced
【讨论】:
v-el 指令似乎不再存在了。
ref="myid" 添加到元素中,但必须在 JavaScript 中使用 this.$refs["myid"] 引用它。
:ref="'item' + item.id"。但是,这很少是必要的,因为在循环中定义的 refs 会自动进入数组 this.$refs['combo-inside-loop'][index]
如果您从 DOM 元素开始,请检查该元素上的 __vue__ 属性。任何 Vue 视图模型(组件,由 v-repeat 使用创建的 VM)都将具有此属性。
您可以使用浏览器开发者控制台(至少在 Firefox 和 Chrome 中)中的“检查元素”功能来查看 DOM 属性。
希望有帮助!
【讨论】:
c = $0.__vue__。现在c 是你的 Vue 组件,你可以检查它的所有属性。 :)
就这样(在“方法”中的方法中):
element = this.$el;
:)
【讨论】:
methods 中,则您已经通过 this 引用了该组件。
this.$el 只是一个 HTML 注释对象,甚至不是根对象。
mounted()之后依赖这个。例如在created() 这是undefined
【讨论】:
由于在 Vue 2.0 中,似乎没有可用的解决方案,我发现一个干净的解决方案是创建一个 vue-id 属性,并将其设置在模板上。然后在 created 和 beforeDestroy 生命周期中,这些实例在全局对象上更新。
基本上:
created: function() {
this._id = generateUid();
globalRepo[this._id] = this;
},
beforeDestroy: function() {
delete globalRepo[this._id]
},
data: function() {
return {
vueId: this._id
}
}
【讨论】:
由于 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(item,e){
// it contains the bound reference
console.log(this.$refs['key'+item.id]);
}
}
});
【讨论】:
所以我认为$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)
$0.__vueComponent__。如果你想要更多,你可以使用$0.__vue__.$parent。这意味着如果 3 个组件共享同一个 dom 节点,则您必须编写 $0.__vue__.$parent.$parent 才能获取主要组件。这种方法不那么简洁,但可以提供更好的控制。
【讨论】:
在 Vue.js 2 中的 Vue 实例中或组件:
this.$el 获取实例/组件安装到的HTMLElement来自HTMLElement:
.__vue__
var vueInstance = document.getElementById('app').__vue__;
在名为vnode 的变量中包含VNode,您可以:
vnode.elm 获取VNode 被渲染到的元素vnode.context获取声明VNode组件的VueComponent实例(这通常返回父组件,但使用slots时可能会让您感到惊讶。vnode.componentInstance获取VNode所在的Actual VueComponent实例来源,字面意思:vue/flow/vnode.js。
Vue.config.productionTip = false; // disable developer version warning
console.log('-------------------')
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('[DIRECTIVE] My Element is:', vnode.elm);
console.log('[DIRECTIVE] My componentInstance is:', vnode.componentInstance);
console.log('[DIRECTIVE] My context is:', vnode.context);
// some properties, such as $el, may take an extra tick to be set, thus you need to...
Vue.nextTick(() => console.log('[DIRECTIVE][AFTER TICK] My context is:', vnode.context.$el))
}
})
new Vue({
el: '#app',
mounted: function() {
console.log('[ROOT] This Vue instance is mounted at element:', this.$el);
console.log('[ROOT] From the element to the Vue instance:', document.getElementById('app').__vue__);
console.log('[ROOT] 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>
【讨论】:
vm._vnode = vnode 有了它,你可以遍历 DOM 节点树,即VNode (VDOM) 树和 Vue 树。
vnode.elm 记录在哪里?
context 是 Vue 实例(根组件)。 componentInstance 是组件实例(可能是根组件,也可能不是根组件。如果它是您创建的自定义组件的实例——例如,通过Vue.component('my-comp', { ...}),它就不是根组件)。
vnode.context.$el (jsfiddle.net/acdcjunior/9emvr5az/2) 对你有用。似乎vnode.context 指向组件被声明 的元素。在那个小提琴的情况下,<Child> 在根中声明(“插入”到<Parent>)跨度>
我找到了这个 sn-p here。这个想法是在 DOM 节点层次结构中向上,直到找到 __vue__ 属性。
function getVueFromElement(el) {
while (el) {
if (el.__vue__) {
return el.__vue__
} else {
el = el.parentNode
}
}
}
在 Chrome 中:
【讨论】:
this.$el - 指向组件的根元素this.$refs.<ref name> + <div ref="<ref name>" ... - 指向嵌套元素 ?仅在vue lifecycle的
mounted()步骤之后使用$el/$refs
<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>
【讨论】:
我需要创建一个导航栏并在外部单击时折叠菜单项。我在mounted生命周期钩子中的windows上创建了一个点击监听器,如下
mounted() {
window.addEventListener('click', (e)=>{
if(e.target !== this.$el)
this.showChild = false;
})
}
你也可以检查元素是否是 this.$el 的子元素。但是,在我的情况下,孩子都是链接,这并不重要。
【讨论】: