在计算属性中使用$ refs


85

我如何访问$refs内部计算?第一次运行计算属性始终是未定义的。


6
是的,仅在第一个渲染循环完成时才定义。对于它的价值,明确建议不要在计算属性内使用$ refs,因为它没有反应性。vuejs.org/v2/guide/components.html#Child-Component-Refs您可能必须找到一个更好的模式...
Cobaltway

使用已安装支架内的手表功能在此处输入链接描述
Phong Tran

Answers:


128

要在这里回答我自己的问题,在其他任何地方都找不到满意的答案。有时您只需要访问dom元素即可进行一些计算。希望这对其他人有帮助。

安装组件后,我不得不欺骗Vue更新计算属性。

Vue.component('my-component', {
    data(){
        return {
            isMounted: false
        }
    },
    computed:{
        property(){
            if(!this.isMounted)
                return;
            // this.$refs is available
        }
    },
    mounted(){
        this.isMounted = true;
    }
})

2
具有完全相同的要求,这是我找到的唯一可行的解​​决方案。如果将嵌套属性(ref)设置了某些属性,则将class属性绑定到计算属性,并且必须应用某些类。
Christophe Geers '19

@Bondsmith对不起哈哈,我是提问者和回答者,我猜我忘了接受自己的回答
Eric Guan)

我没意识到 '
邦德史密斯

非常有帮助,谢谢@EricGuan花时间回答您自己的问题以帮助他人
timmyLtus

18

我认为引用Vue js指南很重要:

$ refs仅在呈现组件之后填充,并且它们是无反应的。它仅用作直接子操作的转义线-您应避免从模板或计算的属性中访问$ refs。

因此,尽管您总是可以绕开它,但是这不是您应做的事情。


15

如果您需要$refs之后,v-if可以使用updated() 挂钩。

<div v-if="myProp"></div>


updated() {
    if (!this.myProp) return;
    /// this.$refs is available
},

整洁的把戏!将v-if条件合并到computed的逻辑中,以便将它们注册为依赖项。refv-if
精确地

6

我刚遇到同样的问题,并且意识到这是计算属性无法使用的情况。

根据当前文档(https://vuejs.org/v2/guide/computed.html):

“ [...]我们可以定义与方法相同的功能,而不是计算属性。对于最终结果,这两种方法确实完全相同。但是,不同之处在于,计算属性是根据其反应性进行缓存的计算属性只会在其某些反应性依赖项已更改时重新评估

因此,在这些情况下(可能)发生的事情是,完成组件的已安装生命周期并设置引用不会算作对计算属性依赖项的反应性更改。

例如,在我的情况下,当我的参考表中没有选定的行时,我需要禁用一个按钮。因此,此代码将不起作用:

<button :disabled="!anySelected">Test</button>

computed: {
    anySelected () {
      if (!this.$refs.table) return false

      return this.$refs.table.selected.length > 0
    }
}

您可以做的是将计算的属性替换为方法,并且应该可以正常工作:

<button :disabled="!anySelected()">Test</button>

methods: {
    anySelected () {
      if (!this.$refs.table) return false

      return this.$refs.table.selected.length > 0
    }
}

3
我认为这种方法是迄今为止最好的方法。它不传播指示出来data()updated()和其他部件。干净简洁。
MongoLato

3

对于像我这样只需要传递一些数据到道具的其他用户,我使用data而不是computed

Vue.component('my-component', {
    data(){
        return {
            myProp: null
        }
    },    
    mounted(){
        this.myProp= 'hello'    
        //$refs is available              
        // this.myProp is reactive, bind will work to property
    }
})

1

如果需要,请使用属性绑定。:禁用的道具在这种情况下是反应性的

<button :disabled="$refs.email ? $refs.email.$v.$invalid : true">Login</button>

但是要检查两个字段,我发现没有其他方法可以用作虚拟方法:

<button
    :disabled="$refs.password ? checkIsValid($refs.email.$v.$invalid, $refs.password.$v.$invalid) : true">
            {{data.submitButton.value}}
</button>

methods: {
   checkIsValid(email, password) {
      return email || password;
   }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.