【问题标题】:Why does the vue documentation say refs are not reactive when indeed they are为什么 vue 文档说 refs 不是响应式的,而实际上它们是响应式的
【发布时间】:2019-02-28 14:15:30
【问题描述】:

the vue official documentation 的引述指出

$refs...不是反应式的。

但是,我在模板中使用了这样的 ref,它们确实是反应式的,甚至在方法、计算的 props 和 watchers 中(只要您在挂载后访问它)。几个第三方 vue 库e.g. this one 也提供了使用/依赖于 refs 反应性的功能。

有人可以澄清一下官方文档中的 refs 不是响应式的意思吗?

【问题讨论】:

  • 当组件中存在链接到 $refs 的依赖项时,依赖属性数据的更改不会触发 $ref 中的重新渲染,直到再次挂载 DOM。这是一个例子:stackoverflow.com/questions/50040027/…
  • @I'mOnlyVueman 您的评论表明“反应式”仅适用于 UI 状态(因此您说“触发重新渲染”),而数据的状态已经持久化 - 它只是一个等到下一次 DOM 更新的问题。这种“延迟”是否有资格不做出反应? (我只是想了解对象“反应性”的真正含义)
  • 我的理解是响应式的,至少在 Vue 的意义上,意味着 DOM 将执行 tree-shaking 来更新需要更新的特定数据元素,而剩下的虚拟 DOM 原样。所以在 $refs 的情况下,虚拟 DOM 不会执行这个更新过程,尽管被发送了更新的数据,因为 $refs 在 Vue 的摇树过程中是不被识别的。因此,一旦重新渲染整个虚拟 DOM,$refs 就会更新。可能值得让专家确认或修改。

标签: vue.js


【解决方案1】:

您误解了在 Vue 框架的上下文中响应式的含义。当然,您可以在安装组件时设置 $refs 对象的值,但这并不意味着该对象是反应性的。

当数据是反应式时,这意味着对该数据值的更改将触发依赖于该数据值的组件的某些部分的“反应”,例如重新渲染模板,重新计算计算变量,或触发观察者。

Read through the documentation on reactivity.


这是一个例子:

Vue.config.productionTip = false;
Vue.config.devtools = false;

new Vue({
  el: '#app',
  mounted() {
    console.log('$refs.foo in mounted', this.$refs.foo);  
  },
  watch: {
    '$refs.foo':{
      immediate: true,
      handler(value) {
        console.log('$refs.foo watcher', value);
      }
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div ref="foo"></div>
  <div v-if="$refs.foo">
    If $refs.foo was reactive, the template would update and you would see this message
  </div>
</div>

在该示例中,您可以看到$refs.foo 的观察程序最初记录$refs.foo 的值是undefined。这是有道理的,因为观察者在组件安装之前已经触发,所以$refs 对象的属性还没有设置。然后,在mounted钩子中,我们看到$refs.foo的值已经按预期设置了。

如果$refs 是响应式的,那么我们会看到模板更新,因为v-if="$refs.foo" 指令将评估为true。在设置$refs.foo 的值后,我们还会看到观察者再次触发,记录$refs.foo 的新值。然而,由于$refs 不是反应式的,所以这些事情都不会发生。

【讨论】:

  • 完美!谢谢。
猜你喜欢
  • 1970-01-01
  • 2022-11-27
  • 1970-01-01
  • 2018-12-18
  • 2019-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-27
相关资源
最近更新 更多