Использование $refs в вычисленном свойстве

Как получить доступ к $refs внутри вычисленного? Он всегда undefined при первом запуске вычисляемого свойства.

Ответ 1

Собираясь ответить на свой вопрос здесь, я не мог найти удовлетворительного ответа где-либо еще. Иногда вам просто необходим доступ к элементу 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

Если вам понадобится $refs после v-if, вы можете использовать hook updated().

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


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

Ответ 3

Я думаю, что важно процитировать руководство Vue JS:

$ refs заполняются только после визуализации компонента и не реагируют. Он предназначен только как аварийный штрих для прямых дочерних манипуляций - вам следует избегать доступа к $ refs из шаблонов или вычисляемых свойств.

Поэтому это не то, что вы должны делать, хотя вы всегда можете взломать его.

Ответ 4

Для других пользователей, таких как я, которым нужно просто передать некоторые данные для поддержки, я использовал 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
    }
})

Ответ 5

Используйте привязку свойств, если хотите. : отключенный опорный сигнал является реактивным в этом случае

<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;
   }
}

Ответ 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
    }
}