这里记录的都是和处理边界情况有关的功能,即一些需要对 Vue 的规则做一些小调整的特殊情况。不过注意这些功能都是有劣势或危险的场景的。我们会在每个案例中注明,所以当你使用每个功能的时候请稍加留意。
访问元素和组件
在绝大多数的情况下,我们最好不要去触发操作另一个组件内部的dom元素,不过确实也存在一些情况下做这些事是合适的。
访问父级组件实例
和 $root
类似,$parent
属性可以用来从一个子组件访问父组件的实例。它提供了一种机会,可以在后期随时触达父级组件,以替代将数据以 prop
的方式传入子组件的方式。
在绝大多数情况下,触达父级组件会使得你的应用更难调试和理解,尤其是当你变更了父级组件的数据的时候。当我们稍后回看那个组件的时候,很难找出那个变更是从哪里发起的。
访问子组件实例或者子元素
尽管存在prop和事件,我们有时候还是需要在js中直接访问一个子组件,为了达到这个目的,你可以通过 ref 特性为这个子组件赋予一个 ID 引用。例如:
<base-input ref="usernameInput"></base-input>
然后我们就可以在父组件中调用到这个子组件了。
而且还可以调用子组件中的方法。
this.$refs.usernameInput
这不仅仅能用在组件上,还可以使用在普通的元素上。
<input ref="input">
methods: {
// 用来从父级组件聚焦输入框
focus: function () {
this.$refs.input.focus()
}
}
这样就允许父级组件通过下面的代码聚焦<base-input>
里的输入框:
this.$refs.usernameInput.focus()
也就是说:
首先在子组件<base-input>
中定义foucus
方法,这个方法就是使用ref
调用input
聚焦输入框。
然后父组件中通过 ref
调用子组件和他的 foucus
方法,就实现了。
当 ref 和 v-for 一起使用的时候,你得到的引用将会是一个包含了对应数据源的这些子组件的数组。
$refs
只会在组件渲染完成之后生效,并且它们不是响应式的。这只意味着一个直接的子组件封装的“逃生舱”——你应该避免在模板或计算属性中访问 $refs
。
程序化的事件侦听器
现在,你已经知道了$emit
(子组件触发父组件方法,并且可以传递第二个参数作为值) 的用法,它可以被v-on
侦听,但是 Vue 实例同时在其事件接口中提供了其它的方法。我们可以:
通过 $on(eventName, eventHandler)
侦听一个事件
通过 $once(eventName, eventHandler)
一次性侦听一个事件
通过 $off(eventName, eventHandler)
停止侦听一个事件
你通常不会用到这些,但是当你需要在一个组件实例上手动侦听事件时,它们是派得上用场的。
注意 Vue 的事件系统不同于浏览器的 EventTarget API。尽管它们工作起来是相似的,但是 $emit
、$on
, 和 $off
并不是 dispatchEvent
、addEventListener
和 removeEventListener
的别名。
递归组件
组件可以在自己的模板中调用自身,不过他们只能通过 name
选项来做这件事。
name: 'unique-name-of-my-component'
当你使用 Vue.component
全局注册一个组件时,这个全局的 ID 会自动设置为该组件的 name
选项。
Vue.component('unique-name-of-my-component', {
// ...
})