我想将ref属性附加到具有自定义指令的HTML元素上。
假设我有一个名为v-custom
的指令,并且每当在元素上使用它时,我都希望将ref="elem"
添加到元素中。
我尝试使用类似这样的指令:
Vue.directive('custom', {
inserted(el) {
el.setAttribute("ref", "elem");
}
});
在我的组件之一中,我有这个:
<span v-custom>Testing</span>
当我在网页中查看它时,我可以检查该span元素并看到它具有ref属性,但是当我检查它所属的组件的ref时,它表示它不包含“ elem” ref。 / p>
但是,如果我自己添加ref标签,就像这样:
<span v-custom ref="elem">Testing</span>
然后按预期工作,我可以在控制台中看到“ elem”参考。
有什么办法可以使我的用例工作,或者这是预期的行为?
答案 0 :(得分:1)
正如@skirtle所指出的,ref
在vue模板代码中被编写为普通的DOM属性,但是在解析时的处理方式有所不同。 Vue组件实例/视图模型/“ vm”具有对象vm.$refs
,该对象将键映射到DOM元素。我们可以自己修改该对象。然后的问题是如何从指令中获取父项vm
(我们已经获得了DOM元素el
)。
查看自定义指令https://vuejs.org/v2/guide/custom-directive.html#Directive-Hook-Arguments的文档,我们可以看到第三个参数是“ vnode”引用,而查看其文档,我们可以看到vnode.context
引用了容器vm;因此:
Vue.directive('my-directive', {
inserted (el, binding, vnode) {
console.log('directive inserted')
const refKey = "s2"
vnode.context.$refs[refKey] = el // set it
}
})
Vue.component('my-component', {
template: '#my-component-template',
replace: false,
props: {text: String},
mounted () {
console.log('component mounted')
this.$refs.s1.innerText = 's1 ref working'
this.$refs.s2.innerText = 's2 ref working' // use it
}
});
new Vue({
el: '#app',
data: {
status: "initialized",
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
hello
<my-component :text="status"></my-component>
</div>
<script type="text/x-template" id="my-component-template">
<div>
{{text}}, <!-- to illustrate props data passing working as usual -->
<span ref="s1"></span>, <!-- to illustrate a normal ref -->
<span class="nested"> <!-- to illustrate vnode.context doesn't just get the parent node -->
<span v-my-directive></span>
</span>
</div>
</script>
运行此示例,我们可以看到v-my-directive在运行vm中的vm.$refs.s2
函数之前,成功修改了mounted
以使用指令引用DOM元素,在这里我们可以使用参考。
请注意,如果有多个元素包含指令,您可能希望某些逻辑不覆盖ref。
编码愉快!