Vuejs: нет доступа к (вычисляемым) реквизитам в цикле вычисленных свойств

Возможно, очевидный, но у меня есть однофайловый компонент Vue вроде этого:

<template>
...
</template>

<script>
    export default {
        props: [ 'matches', 'results' ],

        computed: {

           formattedMatches: function () {
                let rows = [];
                this.matches.forEach(function($match, $i) {
                    rows[$i] = {
                        id: $i + 1,
                        title: $match[0] + ' ' + $match[1]
                    };
                });
                return rows;
            },

            formattedResults: function () {
                let rows = [];
                this.results.forEach(function($resultRow, $i) {
                    rows[$i] = {
                        id: $i + 1,
                        title: this.formattedMatches[$i]     
 // Error in render: "TypeError: Cannot read property 'formattedMatches' of undefined"
                    };
                });
                return rows;
            },
    ...
</script>

Ошибка появляется также, если я пытаюсь использовать this.matches, а не только this.formattedMatches. Я полагаю, что это вопрос переменных в пределах классов и методов, но я даже не знаю, есть ли другой лучший способ или шаблон для достижения того же поведения.

Любые идеи? Заранее спасибо.


person andcl    schedule 25.09.2018    source источник


Ответы (2)


this имеет другой контекст в анонимной функции forEach. Самое простое решение - использовать обозначение стрелочной функции.

this.results.forEach(($resultRow, $i) => {
    rows[$i] = {
        id: $i + 1,
        title: this.formattedMatches[$i]
    };
});
person Stephen Thomas    schedule 25.09.2018
comment
Спасибо, Стивен, он тоже работает, как ожидалось. Я опубликовал эквивалентное решение прямо сейчас. - person andcl; 25.09.2018

Нашел решение, основанное на другом решении на StackOverflow. Как говорится, this внутри обратного вызова относится к самому обратному вызову (или, скорее, как указано, контекст выполнения обратного вызова), а не к экземпляру Vue. Если вы хотите получить к нему доступ, вам нужно либо назначить его чему-то за пределами обратного вызова.

Так что в моем случае ...

...
formattedResults: function () {
     let self = this;
     let rows = [];
     this.results.forEach(function($resultRow, $i) {
         rows[$i] = {
              id: $i + 1,
              title: self.formattedMatches[$i]     
         };
     });
     return rows;
},
...

... делает свое дело. Спасибо, в любом случае!

person andcl    schedule 25.09.2018