边界处理情况,一些需要对 Vue 的规则做一些小调整的特殊情况。
不过注意这些功能都是有劣势或危险的场景的。我们会在每个案例中注明,所以当你使用每个功能的时候请稍加留意。
- 访问元素&组件
- 访问根元素:$root this.root.foo
- 访问父级元素:$parent this.$parent.$parent.map
(更推荐依赖注入) - 访问子组件实例或子元素:$ref
$refs
只会在组件渲染完成之后生效,并且它们不是响应式的。这仅作为一个用于直接操作子组件的“逃生舱”——你应该避免在模板或计算属性中访问$refs
。 -
依赖注入:provide、inject
然而,依赖注入还是有负面影响的。它将你应用程序中的组件与它们当前的组织方式耦合起来,使重构变得更加困难。同时所提供的 property 是非响应式的。这是出于设计的考虑,因为使用它们来创建一个中心化规模化的数据跟使用$root
做这件事都是不够好的。如果你想要共享的这个 property 是你的应用特有的,而不是通用化的,或者如果你想在祖先组件中更新所提供的数据,那么这意味着你可能需要换用一个像 Vuex 这样真正的状态管理方案了。
-
程序化的事件监听器:$on('...','...')、$once、$off
注意 Vue 的事件系统不同于浏览器的 EventTarget API。尽管它们工作起来是相似的,但是$emit
、$on
, 和$off
并不是dispatchEvent、
addEventListener
和removeEventListener
的别名。-
vm.$on( event, callback ):监听当前实例上的自定义事件。事件可以由
vm.$emit
触发。回调函数会接收所有传入事件触发函数的额外参数。 -
vm.$once( event, callback ):监听一个自定义事件,但是事件只触发一次。一旦触发后,监听器就会被移除。
-
vm.$off( [event, callback] ):移除自定义事件监听器。
-
如果没有提供参数,则移除所有的事件监听器;
-
如果只提供了事件,则移除该事件所有的监听器;
-
如果同时提供了事件与回调,则只移除这个回调的监听器。
-
-
-
循环引用
-
递归组件:name,组件在自己的模板中调用自己。
循环组件可能会导致“max stack size exceeded”错误,所以请确保递归调用是条件性的 (例如使用一个最终会得到false
的v-if
)。 -
组件之间的循环引用
你会发现循环引用组件在渲染树中互为对方的后代和祖先——一个悖论!-
全局注册组件的时候,这个悖论会被自动解开。
-
我们先把两个组件称为 A 和 B。模块系统发现它需要 A,但是首先 A 依赖 B,但是 B 又依赖 A,但是 A 又依赖 B,如此往复。这变成了一个循环,不知道如何不经过其中一个组件而完全解析出另一个组件。为了解决这个问题,我们需要给模块系统一个点,在那里“A 反正是需要 B 的,但是我们不需要先解析 B。”
-
-
-
模板定义的替代品
-
内联模板:当
inline-template
这个特殊的 attribute 出现在一个子组件上时,这个组件将会使用其里面的内容作为模板,而不是将其作为被分发的内容。这使得模板的撰写工作更加灵活。<my-component inline-template> <div> <p>These are compiled as the component's own template.</p> <p>Not parent's transclusion content.</p> </div> </my-component>
内联模板需要定义在 Vue 所属的 DOM 元素内。
不过,inline-template
会让模板的作用域变得更加难以理解。所以作为最佳实践,请在组件内优先选择template
选项或.vue
文件里的一个<template>
元素来定义模板。 -
X-Template:另一个定义模板的方式是在一个
<script>
元素中,并为其带上text/x-template
的类型,然后通过一个 id 将模板引用过去。<script type="text/x-template" id="hello-world-template"> <p>Hello hello hello</p> </script>
Vue.component('hello-world', { template: '#hello-world-template' })
x-template 需要定义在 Vue 所属的 DOM 元素外。
这些可以用于模板特别大的 demo 或极小型的应用,但是其它情况下请避免使用,因为这会将模板和该组件的其它定义分离开。
-
-
控制更新:
-
强制更新:$forceUpdate
如果你发现你自己需要在 Vue 中做一次强制更新,99.9% 的情况,是你在某个地方做错了事。
如果你已经做到了上述的事项仍然发现在极少数的情况下需要手动强制更新,那么你可以通过$forceUpdate
来做这件事。 -
通过 v-once 创建低开销的静态组件
渲染普通的 HTML 元素在 Vue 中是非常快速的,但有的时候你可能有一个组件,这个组件包含了大量静态内容。在这种情况下,你可以在根元素上添加v-once
attribute 以确保这些内容只计算一次然后缓存起来,
再说一次,试着不要过度使用这个模式。当你需要渲染大量静态内容时,极少数的情况下它会给你带来便利,除非你非常留意渲染变慢了,不然它完全是没有必要的——再加上它在后期会带来很多困惑。例如,设想另一个开发者并不熟悉v-once
或漏看了它在模板中,他们可能会花很多个小时去找出模板为什么无法正确更新。
-