Vuex getter при получении по id возвращает саму функцию?

есть стейт

state: {
    todos: [
      { id: 1, text: 'Первый текст', done: true },
      { id: 2, text: 'Второй текст', done: false }
    ],
},

есть геттер

getters: {
    GET_TODO: (state) => (id) => {  
      return state.todos.find(todo => todo.id === id)
    }
  }

когда пытаюсь получить строку по id

mounted () {
    this.todo = this.GET_TODO(1)
    console.log(this.todo)
  },

в консоль выдает эту функцию а не строку с id = 1. Вопрос почему?


Ответы (4 шт):

Автор решения: Aleksey

Я не спец в javascript но похоже что конструкция

GET_TODO: (state) => (id) => {  
  return state.todos.find(todo => todo.id === id)
}

Равносильна этой

GET_TODO: function name1(state) {
    return function name2(id) {
        return state.todos.find(todo => todo.id === id);
    }
}

Поэтому вызов this.GET_TODO(1) и возвращает функцию

→ Ссылка
Автор решения: Сергей Хохлов

Вот что говорит официальная документация! Стиль обращения как к методам Можно также передавать аргументы геттерам, возвращая функцию. Это например пригодится, когда необходимо возвращать массив по указанному критерию:

getters: {
  // ...
  getTodoById: state => id => {
    return state.todos.find(todo => todo.id === id);
  }
}

store.getters.getTodoById(2); // -> { id: 2, text: '...', done: false }

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

→ Ссылка
Автор решения: Николай Парахневич

Фрагменты вашего кода правильные. Вы не указали как вы подключаете getters в ваш компонент(приложение), но если вы используете вспомогательную функцию mapGetters - значит "проксируете " геттеры хранилища в локальные вычисляемые свойства компонента, все должно работать.

// импортируете mapGetters из vuex 
const {
  mapGetters
} = Vuex

// используете в computed 
...mapGetters(['GET_TODO'])

Если вы не хотите использовать mapGetters, можете использовать синтаксис прямого доступа к геттерам:

  $store.getters['GET_TODO'](2)

Рабочий пример:

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: 'Первый текст', done: true },
      { id: 2, text: 'Второй текст', done: false }
    ],
  },
  getters: {
    GET_TODO: (state) => (id) => {  
      return state.todos.find(todo => todo.id === id)
    }
  },
})
const {
  mapGetters
} = Vuex

const app = new Vue({
  el: '#app',
  store,
  data() {
    return {
      todo: null
    };
  },
  computed: {
    ...mapGetters(['GET_TODO'])
  },
  mounted () {
    this.todo = this.GET_TODO(1)
    console.log(this.todo)
  },
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vuex.js"></script>

<div id="app">
  {{ todo }}
  <hr>
  {{ $store.getters['GET_TODO'](2)}}
</div>

→ Ссылка
Автор решения: Максим Вишневский

Тут вы создаете геттер, который возвращает тоже функцию (state) => (id) => { // тут какая-то логика } (данная конструкция состоит из двух функций, первая вернет сам геттер например в mapGetters, что создаст замыкание аргумента state (кстати тут можно воспользоваться деструктуризацией: ({ todos }) => ...), затем полученную функцию вы можете вызвать с параметром id в своем темплейте/логике компонента):

getters: {
  GET_TODO: ({ todos }) => (id) => todos.find((todo) => todo.id === id) || {},
}

То есть далее вам необходимо воспользоваться к примеру mapGetters.

computed: {
  // и уже далее вы можете использовать вызов GET_TODO(id)
  ...mapGetters('GET_TODO'),
},

Тут стоит заметить, что так использовать геттеры нужно аккуратно, потому что вы теряете основное удобство геттера - это кэширование. Вот статья с советами работы с vuex.

→ Ссылка