首页 > 解决方案 > 为什么 vue 文档说 refs 不是响应式的,而实际上它们是响应式的

问题描述

来自vue 官方文档的引用指出

$refs ...不是被动的。

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

有人可以澄清一下官方文档中裁判没有反应的意思吗?

标签: vue.js

解决方案


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

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

通读有关反应性的文档。


这是一个例子:

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不是反应式的,因此这些事情都不会发生。


推荐阅读