# CRUD Vuex (option api)

Realizaremos una práctica de Vuex y Formularios:

# Create

https://www.npmjs.com/package/shortid (opens new window)

npm i shortid
<template>
  <form class="mt-3" @submit.prevent="procesarFormulario">
    
    <Input :tarea="tarea" />

  </form>

  <hr>
  <p>{{tarea}}</p>
</template>

<script>
import Input from '../components/Input'

export default {
  components: {
    Input
  }
}
</script>

Input.vue

<template>
    <input 
        type="text" 
        placeholder="Nombre Tarea"
        class="form-control"
        v-model.trim="tarea.nombre"
    >

    <!-- checkbox -->
    <div class="my-2">
        <div class="form-check form-check-inline">
        <input 
            type="checkbox"
            class="form-check-input"
            id="check-1"
            v-model="tarea.categoria"
            value="Javascript"
        >
        <label 
            for="check-1"
            class="form-check-label"
        >Javascript</label>
        </div>
        <div class="form-check form-check-inline">
        <input 
            type="checkbox"
            class="form-check-input"
            id="check-2"
            v-model="tarea.categoria"
            value="Desarrollo"
        >
        <label 
            for="check-2"
            class="form-check-label"
        >Desarrollo web</label>
        </div>
    </div>

    <!-- radio -->
    <div class="my-2">
        <div class="form-check form-check-inline">
        <input 
            class="form-check-input" 
            type="radio" 
            id="inlineRadio1" 
            value="urgente"
            v-model="tarea.estado"
        >
        <label class="form-check-label" for="inlineRadio1">
            Urgente
        </label>
        </div>

        <div class="form-check form-check-inline">
        <input 
            class="form-check-input" 
            type="radio" 
            id="inlineRadio2" 
            value="relax"
            v-model="tarea.estado"
        >
        <label class="form-check-label" for="inlineRadio2">
            Relax
        </label>
        </div>
    </div>

    <div class="my-2">
        <input 
        type="number"
        class="form-control"
        placeholder="numero"
        v-model.number="tarea.numero"
        >
    </div>

    <button 
        class="btn btn-block btn-dark" 
        type="submit"
        :disabled="bloquear"
    >
        Agregar
    </button>
</template>

<script>
export default {
    props: {
        tarea: Object
    },
    computed: {
        bloquear(){
            return this.tarea.nombre.trim() === '' ? true : false
        }
    }
}
</script>

vuex

import { createStore } from 'vuex'

export default createStore({
  state: {
    tareas: [],
    tarea: {nombre: '', categoria: [], estado: '', numero: 0}
  },
  mutations: {
    set(state, payload) {
      console.log(payload)
      state.tareas.push(payload)
    }
  },
  actions: {
    setTareas({ commit }, tarea) {
      console.log(tarea)
      commit('set', tarea)
    }
  },
  modules: {
  }
})

Home.vue

<script>
import {mapActions} from 'vuex'

const shortid = require('shortid');

export default {
  data() {
    return {
      tarea: {id: '', nombre: '', categoria: [], estado: '', numero: 0}
    }
  },
  methods: {
    ...mapActions(['setTareas']),
    procesarFormulario(){
      if(this.tarea.nombre.trim() === ''){
        console.log('nombre Vacío')
        return
      }

      this.tarea.id = shortid.generate()
      console.log(this.tarea)

      this.setTareas(this.tarea)

      this.tarea = {id: '', nombre: '', categoria: [], estado: '', numero: 0}
    }
  },
  computed: {
    bloquear(){
      return this.tarea.nombre.trim() === '' ? true : false
    }
  }
}
</script>

# Read

ListaTareas.vue (components)

<template>
  <h1>Lista de Tareas</h1>
    <table class="table">
        <thead>
            <tr>
            <th scope="col">#</th>
            <th scope="col">Nombre</th>
            <th scope="col">Categorías</th>
            <th scope="col">Estado</th>
            <th scope="col">Número</th>
            </tr>
        </thead>
        <tbody>
            <tr v-for="(tarea, index) in tareas" :key="index">
                <th scope="row">{{tarea.id}}</th>
                <td>{{tarea.nombre}}</td>
                <td>{{tarea.categoria}}</td>
                <td>{{tarea.estado}}</td>
                <td>{{tarea.numero}}</td>
            </tr>
        </tbody>
    </table>
</template>

<script>
import { mapState } from 'vuex'
export default {
    computed:{
        ...mapState(['tareas'])
    }
}
</script>
<template>
  <h1>Lista de Tareas</h1>
    <table class="table">
        <thead>
            <tr>
            <th scope="col">#</th>
            <th scope="col">Nombre</th>
            <th scope="col">Categorías</th>
            <th scope="col">Estado</th>
            <th scope="col">Número</th>
            </tr>
        </thead>
        <tbody>
            <tr v-for="(tarea, index) in tareas" :key="index">
                <th scope="row">{{index}}</th>
                <td>{{tarea.nombre}}</td>
                <td>
                    <span v-for="(item, i) in tarea.categoria" :key="i">
                        {{
                            tarea.categoria.length  === (index + 1) ? item : item + ', ' 
                        }}
                    </span>
                </td>
                <td>{{tarea.estado}}</td>
                <td>{{tarea.numero}}</td>
            </tr>
        </tbody>
    </table>
</template>

# Delete

import { createStore } from 'vuex'

export default createStore({
  mutations: {
    delete(state, payload) {
      state.tareas = state.tareas.filter(item => item.id !== payload)
    }
  },
  actions: {
    deleteTarea({commit}, id){
      commit('delete', id)
    }
  }
})
<td>
    <button
        class="btn btn-danger btn-sm"
        @click="deleteTarea(tarea.id)"
    >
        Eliminar
    </button>
</td>
<script>
import { mapState, mapActions } from 'vuex'
export default {
    computed:{
        ...mapState(['tareas'])
    },
    methods:{
        ...mapActions(['deleteTarea'])
    }
}
</script>

# Update

ListaTareas.vue

<router-link
    class="btn btn-warning btn-sm"
    :to="{
        name: 'Editar',
        params: {
            id: tarea.id
        }
    }"
>
    Editar
</router-link>
{
  path: '/editar/:id',
  name: 'Editar',
  component: () => import(/* webpackChunkName: "about" */ '../views/Editar.vue')
}
import { createStore } from 'vuex'

export default createStore({
  state: {
    tareas: [],
    tarea: {id: '', nombre: '', categoria: [], estado: '', numero: 0}
  },
  mutations: {
    tarea(state, payload) {
      state.tarea = state.tareas.find(item => item.id === payload)
      console.log('tarea vuex: ', state.tarea)
    }
  },
  actions: {
    setTarea({ commit }, id) {
      commit('tarea', id)
    }
  },
})

Ojo que si refrescas el sitio web la tarea desaparecerá, más adelante veremos como resolverlo con localStorage

<template>
     {{tarea}}
</template>

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

export default {
    computed: {
        ...mapState(['tarea'])
    },
    methods: {
        ...mapActions(['setTarea'])
    },
    created(){
        this.setTarea(this.$route.params.id)
    }
}
</script>

Vuex

// importar
import router from '../router'

//mutations
update(state, payload) {
  state.tareas = state.tareas.map(item => item.id === payload.id ? payload : item)
}

//Actions
updateTarea({ commit }, tarea) {
  commit('update', tarea)
  router.push('/')
}

Agregar Formulario

<template>
    <form class="mt-3" @submit.prevent="updateTarea(tarea)">
    
        <Input :tarea="tarea" />

    </form>

    <hr>
    <p>{{tarea}}</p>
</template>

<script>
import Input from '../components/Input'
import {mapActions, mapState} from 'vuex'

export default {
    components: {
        Input
    },
    computed: {
        ...mapState(['tarea'])
    },
    methods: {
        ...mapActions(['setTarea', 'updateTarea'])
    },
    created(){
        this.setTarea(this.$route.params.id)
    }
}
</script>

Opcionales:

tarea(state, payload) {
  if (!state.tareas.find(item => item.id === payload)){
    console.log('no existe el id')
    router.push('/')
    return 
  }
  state.tarea = state.tareas.find(item => item.id === payload)
  console.log(state.tarea)
  console.log('tarea vuex: ', state.tarea)
},

# LocalStorage

# Leer o crear

// Vuex

// Mutations
cargar(state, payload) {
  state.tareas = payload
}

// Actions
cargarLocalStorage({ commit }) {
  if (localStorage.getItem('tareas1')) {
    console.log('existe')
    const tareas = JSON.parse(localStorage.getItem('tareas1'))
    commit('cargar', tareas)
  } else {
    localStorage.setItem('tareas1', JSON.stringify([]))
  }
}
// App.vue
<template>
  <div class="container mt-2">
    <Navbar />
    <router-view/>
  </div>
</template>

<script>
import Navbar from './components/Navbar'
import {mapActions} from 'vuex'
export default {
  components: {
    Navbar
  },
  methods:{
    ...mapActions(['cargarLocalStorage'])
  },
  created(){
    this.cargarLocalStorage()
  }
}
</script>

# Mutations

 mutations: {
  cargar(state, payload) {
    state.tareas = payload
  },
  set(state, payload) {
    console.log(payload)
    state.tareas.push(payload)
    localStorage.setItem('tareas1', JSON.stringify(state.tareas))
  },
  delete(state, payload) {
    state.tareas = state.tareas.filter(item => item.id !== payload)
    localStorage.setItem('tareas1', JSON.stringify(state.tareas))
  },
  tarea(state, payload) {
    if (!state.tareas.find(item => item.id === payload)){
      console.log('entro aquí')
      router.push('/')
      return 
    }
    state.tarea = state.tareas.find(item => item.id === payload)
    localStorage.setItem('tareas1', JSON.stringify(state.tareas))
  },
  update(state, payload) {
    state.tareas = state.tareas.map(item => item.id === payload.id ? payload : item)
    localStorage.setItem('tareas1', JSON.stringify(state.tareas))
  }
}
Last Updated: 12/8/2022, 15:53:28