En aquest tema, explorarem com gestionar l'estat de l'aplicació utilitzant Vuex, la biblioteca oficial de gestió d'estat per a Vue.js. Vuex segueix el patró Flux i proporciona un emmagatzematge centralitzat per a totes les dades de l'aplicació, permetent una gestió més eficient i estructurada de l'estat.

Continguts

  1. Introducció a l'estat de Vuex
  2. Getters
  3. Mutacions
  4. Accions
  5. Exemple pràctic
  6. Exercicis

  1. Introducció a l'estat de Vuex

L'estat de Vuex és un objecte que conté totes les dades de l'aplicació. Aquest estat és reactiu, el que significa que qualsevol canvi en l'estat es reflectirà automàticament en la interfície d'usuari.

Exemple de configuració de l'estat

// store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    count: 0
  }
});

En aquest exemple, hem creat un estat amb una propietat count inicialitzada a 0.

  1. Getters

Els getters són similars a les propietats computades per a l'estat de Vuex. Permeten accedir a l'estat de manera derivada i poden ser utilitzats per calcular valors basats en l'estat.

Exemple de getters

// store.js
export default new Vuex.Store({
  state: {
    count: 0
  },
  getters: {
    doubleCount: state => state.count * 2
  }
});

En aquest exemple, hem creat un getter doubleCount que retorna el doble del valor de count.

  1. Mutacions

Les mutacions són l'única manera de canviar l'estat de Vuex. Les mutacions són síncrones i es defineixen com a funcions que reben l'estat com a primer argument i un payload opcional com a segon argument.

Exemple de mutacions

// store.js
export default new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    },
    incrementBy(state, payload) {
      state.count += payload.amount;
    }
  }
});

En aquest exemple, hem creat dues mutacions: increment, que incrementa count en 1, i incrementBy, que incrementa count per un valor especificat en el payload.

  1. Accions

Les accions són similars a les mutacions, però poden ser asíncrones. Les accions es defineixen com a funcions que reben un context com a primer argument, el qual conté l'estat, els getters, les mutacions i altres accions.

Exemple d'accions

// store.js
export default new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    incrementAsync({ commit }) {
      setTimeout(() => {
        commit('increment');
      }, 1000);
    }
  }
});

En aquest exemple, hem creat una acció incrementAsync que incrementa count després d'un segon.

  1. Exemple pràctic

Ara que hem vist els conceptes bàsics, anem a crear una aplicació senzilla que utilitzi estat, getters, mutacions i accions.

Configuració de l'estat, getters, mutacions i accions

// store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    count: 0
  },
  getters: {
    doubleCount: state => state.count * 2
  },
  mutations: {
    increment(state) {
      state.count++;
    },
    incrementBy(state, payload) {
      state.count += payload.amount;
    }
  },
  actions: {
    incrementAsync({ commit }) {
      setTimeout(() => {
        commit('increment');
      }, 1000);
    },
    incrementByAsync({ commit }, payload) {
      setTimeout(() => {
        commit('incrementBy', payload);
      }, 1000);
    }
  }
});

Utilització de Vuex en un component

<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double Count: {{ doubleCount }}</p>
    <button @click="increment">Increment</button>
    <button @click="incrementAsync">Increment Async</button>
    <button @click="incrementByAsync({ amount: 5 })">Increment by 5 Async</button>
  </div>
</template>

<script>
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex';

export default {
  computed: {
    ...mapState(['count']),
    ...mapGetters(['doubleCount'])
  },
  methods: {
    ...mapMutations(['increment']),
    ...mapActions(['incrementAsync', 'incrementByAsync'])
  }
};
</script>

En aquest exemple, hem creat un component que mostra el valor de count i doubleCount, i proporciona botons per incrementar count de manera síncrona i asíncrona.

  1. Exercicis

Exercici 1

Crea una aplicació Vuex que gestioni una llista de tasques. L'estat ha de contenir una llista de tasques, i has de proporcionar getters, mutacions i accions per afegir, eliminar i marcar tasques com a completades.

Solució

// store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    tasks: []
  },
  getters: {
    completedTasks: state => state.tasks.filter(task => task.completed),
    pendingTasks: state => state.tasks.filter(task => !task.completed)
  },
  mutations: {
    addTask(state, task) {
      state.tasks.push(task);
    },
    removeTask(state, taskId) {
      state.tasks = state.tasks.filter(task => task.id !== taskId);
    },
    toggleTaskCompletion(state, taskId) {
      const task = state.tasks.find(task => task.id === taskId);
      if (task) {
        task.completed = !task.completed;
      }
    }
  },
  actions: {
    addTaskAsync({ commit }, task) {
      setTimeout(() => {
        commit('addTask', task);
      }, 1000);
    },
    removeTaskAsync({ commit }, taskId) {
      setTimeout(() => {
        commit('removeTask', taskId);
      }, 1000);
    },
    toggleTaskCompletionAsync({ commit }, taskId) {
      setTimeout(() => {
        commit('toggleTaskCompletion', taskId);
      }, 1000);
    }
  }
});

Exercici 2

Modifica l'aplicació de l'exercici anterior per utilitzar mòduls de Vuex per organitzar millor el codi.

Solució

// store/modules/tasks.js
const state = {
  tasks: []
};

const getters = {
  completedTasks: state => state.tasks.filter(task => task.completed),
  pendingTasks: state => state.tasks.filter(task => !task.completed)
};

const mutations = {
  addTask(state, task) {
    state.tasks.push(task);
  },
  removeTask(state, taskId) {
    state.tasks = state.tasks.filter(task => task.id !== taskId);
  },
  toggleTaskCompletion(state, taskId) {
    const task = state.tasks.find(task => task.id === taskId);
    if (task) {
      task.completed = !task.completed;
    }
  }
};

const actions = {
  addTaskAsync({ commit }, task) {
    setTimeout(() => {
      commit('addTask', task);
    }, 1000);
  },
  removeTaskAsync({ commit }, taskId) {
    setTimeout(() => {
      commit('removeTask', taskId);
    }, 1000);
  },
  toggleTaskCompletionAsync({ commit }, taskId) {
    setTimeout(() => {
      commit('toggleTaskCompletion', taskId);
    }, 1000);
  }
};

export default {
  state,
  getters,
  mutations,
  actions
};
// store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
import tasks from './modules/tasks';

Vue.use(Vuex);

export default new Vuex.Store({
  modules: {
    tasks
  }
});

Conclusió

En aquest tema, hem après com gestionar l'estat de l'aplicació utilitzant Vuex. Hem vist com definir l'estat, getters, mutacions i accions, i hem creat una aplicació pràctica per posar en pràctica aquests conceptes. A més, hem proporcionat exercicis per reforçar els coneixements adquirits. En el proper tema, explorarem com utilitzar mòduls a Vuex per organitzar millor el codi de l'aplicació.

Curs de Vue.js

Mòdul 1: Introducció a Vue.js

Mòdul 2: Conceptes bàsics de Vue.js

Mòdul 3: Components de Vue.js

Mòdul 4: Vue Router

Mòdul 5: Gestió d'estat amb Vuex

Mòdul 6: Directives de Vue.js

Mòdul 7: Plugins de Vue.js

Mòdul 8: Proves en Vue.js

Mòdul 9: Conceptes avançats de Vue.js

Mòdul 10: Construcció i desplegament d'aplicacions Vue.js

Mòdul 11: Projectes de Vue.js del món real

© Copyright 2024. Tots els drets reservats