Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Listas

14/23
Recursos

Aportes 12

Preguntas 0

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

Agrego mi solucion al reto, se agrego la funcion eliminar y agregar
Link de github pages
Link del repositorio

_PD. Mi diseño actualmente solo esta optimizado para movil _


Aqui mi avance hasta el momento,
Link de github pages
Link del repositorio

He aplicado un poco de los conocimientos adquiridos en la ruta de ARquitectura de frontend para el diseño.

Utilice el v-for para el listado de los tweets, para entrar a esta seccion se le puede dar click a el boton de google, apple o siguiente

![](_PD. Mi diseño actualmente solo esta optimizado para movil _

![](

Este es mi aporte para el reto de las listas, solo decir que mute directamente el array, deje en comentarios en la parte de quitar un item, algo de como hacer para no mutar directamente los items en el array bindeado a la data, pero no sé si esa práctica sea necesaria en vue
dejo enlace al codigo en un gist codigo listas

<script type="text/javascript">
        const appVue3 = Vue.createApp({
            data() {
                return {
                    addPost:{
                        title: '',
                        description: '',
                    }
                    , editPost: false
                    , openDoor: false
                    , posts: [
                        { title: "Post 1", description: "Description 1"}
                        , { title: "Post 2", description: "Description 2" }
                        , { title: "Post 3", description: "Description 3" }
                        , { title: "Post 4", description: "Description 4" }
                    ]
                    , style: {
                        backgroundColor: '#eca1a6'
                    }
                    , text: "Close door"
                    , userName: ''
                };
            },
            computed: {
                openDoorComputed() {
                    return this.openDoor ? "Close" : "Open";
                }
                , styleComputed(){
                    return {
                        backgroundColor: this.openDoor ? '#b5e7a0' : '#eca1a6'
                    }
                }
                , styleComputed2(){
                    return this.openDoor ? 'open' : 'closed';
                }
            },
            methods: {
                AddPostToTheList(){
                    this.posts.push({
                        title: this.addPost.title
                        , description: this.addPost.description
                    });
                }
                , DeletePost(index, element){
                    // mutabilidad aqui seria para no mutar directamente el array
                    // let aTemp = this.posts.map(function(item, index){
                    //     return item;
                    // });
                    // aTemp.splice(index, 1);
                    // this.posts = aTemp;

                    this.posts.splice(index, 1);
                    // console.log(index, element, this.posts, aTemp);
                }
            },
            watch: {
                openDoor(value, oldValue) {
                    if(value){
                        this.text = "Cierra sesión";
                    }
                    else{
                        this.text = "Inicia sesión";
                        this.userName = '';
                        this.editPost = false;
                    }  
                }
            },
            template: `
                <div class="container" :class="styleComputed2">
                    <h2>{{ text }}</h2>
                    <div v-if="openDoor">
                        <div class="menuLogin">
                                    <a href="#" @click="editPost = true">editar</a>
                                    <a href="#" @click="editPost = false">ver</a>
                        </div>
                        <p>Hola, {{ userName }}</p>                        
                        <div id="divEdit" class="containerEdit" v-if="editPost">
                            <div id="divAddPost" class="addPost">
                                <div> T&iacute;tulo </div>
                                <input type="text" v-model="addPost.title" />
                                <div> Descripci&oacute;n </div>
                                <input type="text" v-model="addPost.description" />
                                <div><button class="btnAdd" @click="AddPostToTheList">Agregar</button></div>
                            </div>
                            <div id="divDeletePost" class="delPost">
                                <div class="itemDel" v-for="(post, i) in posts" key="i">
                                    <div>{{post.title}}</div>
                                    <a href="#" @click="DeletePost(i, post)">borrar</a>
                                </div>    
                            </div>
                        </div>
                        <div v-else class="list">
                            <div class="item" v-for="(post, i) in posts" key="i">
                                <div class="title">{{post.title}}</div>
                                <p>{{post.description}}</p>
                            </div>
                        </div>
                    </div>
                    <div v-else="openDoor">
                        <div>User name </div>
                        <input type="text" v-model="userName">
                    </div>
                    <button @click="openDoor = !openDoor">
                        <div v-if="!openDoor">Acceder</div>
                        <div v-else>Salir</div>
                    </button>
                </div>
            `,
        }).mount("#appVue3");
        console.log(appVue3);
    </script>
    <style>
        html, body {
            height: 100vh;
            margin: 0;
            font-family: Arial, Helvetica, sans-serif;
        }
        #appVue3, .container {
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;
            width: 100%;
            height: 100%;
        }
        button {
            margin-top: 24px;
            border: none;
            background-color: white;
            padding: 8px 24px;
            border-radius: 12px;
        }
        .addPost{
            background-color: #54964a;
            border: 1px solid #ccc;
            padding: 7px;
        }
        .btnAdd {
            border: none;
            background-color: #ced2cf;
            border-radius: 3px;
            color: #16512a;
            font-weight: bold;
            margin-top: 3px;
            padding: 1px 3px;
        }        
        .closed {
            background-color: #eca1a6;
        }
        .containerEdit{
            display: flex;
            flex-direction: row;
            gap: 16px;
            width: 100%;
        }
        .delPost{
            background-color: #54964a;
            border: 1px solid #ccc;
            padding: 7px;
        }
        .open {
            background-color: #b5e7a0;
        }
        .list {
            display: flex;
            flex-direction: column;
        }
        .item{
            border: 1px solid #1c2263;
        }
        .itemDel {
            border-bottom: 1px solid #1c2263;
            font-size: 14px;
            margin-bottom: 7px;
        }
        .menuLogin{
            align-items: center;
            display: flex;
            flex-direction: row;
            gap: 7px;
        }
        .title{
            font-weight: bold;
            font-size: 1.5rem;
        }
    </style>

Esta es mi solución al reto:

const vm = Vue.createApp({
    data(){
        return {
            text : "Accede a tu cuenta",
            open : false,
            username : "",
            posts : [
                {
                    title: "Titulo 1",
                    description : "Lorem ipsum..."
                },
                {
                    title: "Titulo 2",
                    description : "Lorem ipsum..."
                },
                {
                    title: "Titulo 3",
                    description : "Lorem ipsum..."
                },
                {
                    title: "Titulo 4",
                    description : "Lorem ipsum..."
                }
            ],
            newPost: {
                title: '',
                description: ''
            }
        };
    },
    methods: {
        addPost() {
            const setPost = [];
            if ( ( this.newPost.title != "" ) && (this.newPost.description != "") ) {
                setPost['title'] = this.newPost.title;
                setPost['description'] = this.newPost.description;
                this.posts.push(setPost);
                this.newPost.title = "";
                this.newPost.description = "";
            }
        },
        removePost(i){
            this.posts.splice(i, 1);
        }
    },
    watch : {
        open(value){
            if (value) {
                this.text = "Cierra sesión";
            } else {
                this.text = "Accede a tu cuenta";
                this.username = '';
            }
        }
    },
    computed: {
        label(){
            return this.open ? "Salir" : "Acceder";
        },
        styles(){
            return this.open ? 'open' : 'closed';
        }
    },
    template: `
        <div class="container" :class="styles">
            <h2>{{ text }}</h2>
            <div v-if="open">
                <p>Hola, {{ username }} </p>
                <div class="new-post">
                    <h4 class="new-post-heading">Agregar nueva publicación</h4>                            
                    <input type="text" placeholder="Título de la publicación" class="new-post-title" v-model="newPost.title">
                    <textarea placeholder="Descripción" v-model="newPost.description"></textarea>
                    <button class="new-post-publish" @click="addPost">Publicar</button>
                </div>
                <div class="list">
                    <div v-for="(item, i) in posts" :key="i" class="item">
                        <h4 class="title">{{ item.title }} <a href="javascript:void(0)" class="item-remove" @click="removePost(i)">X</a></h4>
                        <p>{{ item.description }}</p>
                    </div>
                </div>
            </div>
            <div v-else>
                <div>Username</div>
                <input type="text" v-model="username">
            </div>
            <button @click="open = !open">{{ label }}</button>
        </div>
    `
}).mount("#app");

El codigo de mi CRUD:

            posts: [
              {
                title: "Titulo 1",
                description: "Lorem ipsum 1",
              },
              {
                title: "Titulo 2",
                description: "Lorem ipsum 2",
              },
              {
                title: "Titulo 3",
                description: "Lorem ipsum 3",
              },
              {
                title: "Titulo 4",
                description: "Lorem ipsum 4",
              },
              {
                title: "Titulo 5",
                description: "Lorem ipsum 5",
              },
            ],
            newPost: {
              title: "",
              content: "",
            },
            postToModify: {
              modifying: false,
              modifiedTitle: "",
              modifiedContent: "",
              indexToModify: null,
            },
 removePost(index) {
            this.posts = this.posts.filter(
              (item) => this.posts.indexOf(item) !== index
            );
          },
          createPost() {
            if (!this.newPost.title || !this.newPost.content) return;
            this.posts = [
              ...this.posts,
              { title: this.newPost.title, description: this.newPost.content },
            ];
          },
          editPost(index) {
            this.postToModify.modifying = true;
            let postToModify = this.posts.filter(
              (item) => this.posts.indexOf(item) === index
            );
            this.postToModify = {
              ...this.postToModify,
              modifiedTitle: postToModify[0].title,
              modifiedContent: postToModify[0].description,
              indexToModify: index,
            };
            console.log(postToModify, this.postToModify);
          },
          modifyPost(indexToModify) {
            this.posts = this.posts.map((item, i) =>
              i !== indexToModify
                ? item
                : {
                    ...item,
                    title: this.postToModify.modifiedTitle,
                    description: this.postToModify.modifiedContent,
                  }
            );
            this.postToModify.modifying = false;
          },

 <div class='list'>
                            Tus Posts:
                            <div v-bind:key='index' v-for='(post, index) in posts' class='item'>
                              <h4>{{post.title}}</h4>
                              <p>{{post.description}}</p>
                              <button v-on:click="removePost(index)" style='margin-bottom:12px'>Eliminar post</button>
                              <button v-on:click='editPost(index)'>Editar Post</button>
                            </div>
                          </div>
                          <div v-if='postToModify.modifying'>
                            <h5>Titulo del Post</h5>
                            <br />
                            <input v-model='postToModify.modifiedTitle' type='text'  />
                            <h5>Contenido del Post</h5>
                            <input v-model='postToModify.modifiedContent' type='text' />
                            <br />
                            <button v-on:click='modifyPost(postToModify.indexToModify)'>Finish editing!</button>
                          </div>
                          <div>
                            <h3>Crear nuevo post</h3>
                            <h5>Titulo del Post</h5>
                            <br />
                            <input type='text' v-model='newPost.title' />
                            <h5>Contenido del Post</h5>
                            <input type='text' v-model='newPost.content'/>
                            <br />
                            <button v-on:click='createPost()'>Post it!</button>
                          </div>

Mi solución al reto:

<script>
import { RouterLink, RouterView } from "vue-router";
import HelloWorld from "@/components/HelloWorld.vue";

export default {
  data() {
    return {
      text: "Accede a tu cuenta",
      open: false,
      username: "",
      nuevoPost: {
        title: null,
        description: null,
      },
      agregarPostTemplate: false,
      mensaje: null,
      posts: [
        {
          title: "Titulo 1",
          description: "Lorem ipsum...",
        },
        {
          title: "Titulo 2",
          description: "Lorem ipsum...",
        },
        {
          title: "Titulo 3",
          description: "Lorem ipsum...",
        },
        {
          title: "Titulo 4",
          description: "Lorem ipsum...",
        },
      ],
    };
  },
  watch: {
    open(value) {
      if (value) {
        this.text = "Cierra sesión";
      } else {
        this.text = "Accede a tu cuenta";
        this.username = "";
      }
    }
  },
  computed: {
    label() {
      return this.open ? "Salir" : "Acceder";
    },
    styles() {
      return this.open ? ["open"] : ["closed"];
    },
  },
  methods: {
    borrarPost(title, i) {
      return this.posts.findIndex((post) => post.title === title) === i
        ? this.posts.splice(i, 1)
        : this.posts;
    },
    agregarPost() {
      if (this.nuevoPost.title === null && this.nuevoPost.description === null) {
        this.mensaje = "Debes darle un título y una descripción a tu nuevo post para agregarlo"
        return
      }
      this.posts.push({
        title: this.nuevoPost.title,
        description: this.nuevoPost.description
        });
      this.agregarPostTemplate = false;
    },
  },
};
</script>

<template>
  <div class="container" :class="styles">
    <h2>{{ text }}</h2>
    <div v-if="agregarPostTemplate">
      <form @submit.prevent="agregarPost">
        <label for="">Agregar post</label> <br />
        <label>Título</label>
        <input
          type="text"
          placeholder="Título"
          v-model="nuevoPost.title"
        /><br />
        <label>Descripción</label
        ><input
          type="text"
          placeholder="Descripción"
          v-model="nuevoPost.description"
        /><br />
        <button
          type="button"
          @click="agregarPost"
          @keypress.enter="agregarPost"
        >
          Agregar
        </button>
        <p style="color: red; font-size: 10px;" v-show="mensaje">{{ mensaje }}</p>
        <p @click="agregarPostTemplate = false">⬅️</p>
      </form>
    </div>
    <div v-else-if="open && !agregarPostTemplate">
      <div class="add-item-container">
        <div>
          <p>Hola, {{ username }}</p>
        </div>
        <div>
          <p @click="agregarPostTemplate = true">🖊️</p>
        </div>
      </div>
      <div class="list">
        <div v-for="(item, i) in posts" :key="i" class="item">
          <div class="item-container">
            <div class="title">{{ item.title }}</div>
            <p>{{ item.description }}</p>
            <p @click="borrarPost(item.title, i)"></p>
          </div>
        </div>
      </div>
    </div>
    <div v-else>
      <div>Username</div>
      <input type="text" v-model="username" />
    </div>
    <button @click="open = !open">
      <div v-if="!open">Acceder</div>
      <div v-else>Salir</div>
    </button>
  </div>
</template>

<style>
html,
body {
  height: 100vh;
  margin: 0;
  font-family: Arial, Helvetica, sans-serif;
}
#app,
.container {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  width: 100%;
  height: 100%;
}
button {
  margin-top: 24px;
  border: none;
  background-color: white;
  padding: 8px 24px;
  border-radius: 12px;
}
.closed {
  background-color: #eca1a6;
}
.open {
  background-color: #b5e7a0;
}
.list {
  display: flex;
  flex-direction: column;
}
.item {
  border: 1px solid black;
}
.title {
  font-weight: bold;
  font-size: 1.2rem;
}
.item-container {
  padding: 1rem;
  min-width: 10rem;
}
.add-item-container {
  display: flex;
  justify-content: space-between;
}
.item-container p {
  width: 100%;
}
</style>

El desafío de esta clase lo resolví con dos methods removeItem(idx) y addItem(postTitle, postDesc). Los argumentos que reciben dichos methods (data) son ingresados por el usuario desde la vista definida en el template (v-model). Debajo les comparto el fragmento de código con la solución:

    <script>
        const vm = Vue.createApp({
            data() {
                return {
                    idx: 0,
                    postTitle: 'Default title',
                    postDesc: 'Default description'
                };
            },
            methods: {
                removeItem(idx) {
                    if(idx > -1 && idx < this.posts.length) {
                        this.posts.splice(idx, 1);
                    }
                },
                addItem(postTitle, postDesc) {
                    this.posts.push( {title: postTitle, desc: postDesc} );
                }
            },
            template:
                 `
            <div class="container">
                <div>{{ today }}</div>
                <br>
                <div v-if="open">
                    <h2 :style="styles">{{ sessionSubject }}</h2>
                    <div :style="{ fontFamily: 'sans-serif' }">Hola, {{ username }} </div>
                    <div class="list">
                        <div v-for="(item, i) in posts" :key="i" class="item">
                            <h4>{{ item.title }}</h4>
                            <p>{{ item.desc }}</p>
                        </div>
                        <label>Quitar item nro: </label>
                        <input type="text" v-model="idx" />
                        <button @click="removeItem(idx)">Quitar</button>
 
                        <h2 :style="styles">Agregar post: </h2>
                        <label>Título: </label>
                        <input type="text" v-model="postTitle" />
                        <label>Descripción: </label>
                        <input type="text" v-model="postDesc" />
                        <button @click="addItem(postTitle, postDesc)">Agregar</button>
                    </div>
                </div>
                <div v-else>
                `
        }).mount("#app");
        console.log(vm);
    </script>

En las vue.js dev tools pueden ver el índice del elemento sobre el que están iterando, me parece muy útil

comparto mi reto :

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src="https://unpkg.com/[email protected]"></script>
  <div id="app">
    
  </div>
  <style>
    html, body {
        height: 100vh;
        margin: 0;
        font-family: Arial, Helvetica, sans-serif;
    }
    #app, .container {
        display: flex;
        justify-content: center;
        align-items: center;
        flex-direction: column;
        width: 100%;
        height: 100%;
    }
    button {
        margin-top: 24px;
        border: none;
        background-color: white;
        padding: 8px 24px;
        border-radius: 12px;
    }
    .closed {
        background-color: #eca1a6;
    }
    .open {
        background-color: #b5e7a0;
    }
    .list {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      width: 100%;
      height: 100%;
    }
    .item {
      margin-top: 15px;
      width: 100%;
      flex-direction: column;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .title {
      font-size: 24px;
      font-weight: bold;
    }
</style>
  <script>
    const vm = Vue.createApp({
      data() {
        return {
          text: "Accede a tu cuenta",
          open:false,
          username: "",
          title: "",
          body:"",
          posts: [{
            title: "Titulo 1",
            body: "Contenido 1",
            id: 1
          },
          {
            title: "Titulo 2",
            body: "Contenido 2",
            id: 2
          },
          {
            title: "Titulo 3",
            body: "Contenido 3",
            id: 3
          }]
        };
      },
      watch :{
        open(value){
          if(value) {
            this.text = "Cierra Sesion";
          } else {
            this.username = "";
            this.text = "Accede a tu cuenta";
          }
        }
      },
      computed: {
        label() {
          return this.open ? "Salir" : "Acceder";
        },
        styles() {
          return this.open ? ['open'] : ['closed'];
        }
      },
      methods: {
        addPost(){
          this.posts.push({
            title: this.title,
            body: this.body,
            id: this.posts.length + 1
          });
          this.title = "";
          this.body = "";
        },
        removePost(id){
          this.posts = this.posts.filter(post => post.id !== id);
        },
      },
      template: `<div class="container" :class="styles">
        <h2>{{text}}</h2>
        <div v-if="open">
          <p>Hola {{username}}</p>
          <div class="list">
            <div v-for="item in posts" :key="item.id" class="item">
              <div class="title">{{item.title}}</div>
              <p>{{item.body}}</p>
              <button @click="removePost(item.id)">Remover  post</button>
            </div>  
          </div>

          <div>
            <input type="text" v-model="title" placeholder="title"/>
            <input type="text-area" v-model="body" placeholder="Description"/>
            <button @click="addPost">Agregar</button>
          </div>
        </div>
        <div v-else>
          <div>Username</div>
          <input type="text" v-model="username"/>
        </div>
        <button @click="open = !open" >
          <div v-if="!open">Acceder</div>
          <div v-else>Salir</div>
        </button>
        </div>
        `
    }).mount("#app");
    console.log(vm)
  </script>
</body>
</html>
const vm = Vue.createApp({
    data() {
        return {
            text: "Acceder a tu cuenta",
            open: false,
            username: "",
            posts: [
                {
                    title: 'Titulo 1',
                    description: 'Lorem ipsum 1'
                },
                {
                    title: 'Titulo 2',
                    description: 'Lorem ipsum 2'
                },
                {
                    title: 'Titulo 3',
                    description: 'Lorem ipsum 3'
                },
                {
                    title: 'Titulo 4',
                    description: 'Lorem ipsum 4'
                },
            ],
            new_post: {
                title: "",
                description: ""
            }
        }
    },
    methods: {
        save() {
            this.posts.push({
                title: this.new_post.title, 
                description: this.new_post.description
            });
            this.new_post.title = "";
            this.new_post.description = "";
        },
        destroy(item) {
            this.posts.splice(item, 1);
        }
    },
    watch: {
        open(value) {
            if (value) {
                this.text = "Cerrar sesión"
            } else {
                this.text = "Acceder a tu cuenta"
                this.username = "";
            }
        }
    },
    computed: {
        label() {
            return this.open ? "Salir" : "Acceder"
        },
        styles() {
            return this.open ? ['open']: ['close']
        }
    },
    template: `
        <div class="container" :class="styles">
            <h2>{{ text }}</h2>
            <div v-if="open">
                <p>Hola, {{ username }}</p>
                <div class="list">
                    <div class="item" v-for="(post, i) in posts" :key="i">
                        <div class="title">{{ post.title }}</div>
                        <p>{{ post.description }}</p>
                        <a href="#" @click="destroy(i)">Eliminar</a>
                    </div>
                </div>
            </div>
            <div v-else>
                <div>Username</div>
                <input type="text" v-model="username" />
            </div>
            <div v-if="open">
                <input v-model="new_post.title" type="text" placeholder="Title">
                <input v-model="new_post.description" type="text" placeholder="Description">
                <button @click="save">Agregar</button>
            </div>
            <button @click="open = !open">
                <div v-if="!open">Acceder</div>
                <div v-else>Salir</div>
            </button>
        </div>
    `
}).mount("#app");

Aquí el pequeño crud de los post

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="https://unpkg.com/[email protected]"></script>
    <div id="app"></div>
    <script>
        const vm = Vue.createApp({
            data() {
                return {
                    text: "Accede a tu cuenta",
                    open: false,
                    username: "",
                    titlepost: '',
                    descriptionpost: '',
                    posts: [{
                      title: "Titulo 1",
                      description: "Lorem ipsum..."
                  }, {
                      title: "Titulo 2",
                      description: "Lorem ipsum..."
                  }]
                };
            },
            watch: {
                open(value) {
                    if (value) {
                        this.text = "Cierra sesión";
                    } else {
                        this.text = "Accede a tu cuenta";
                        this.username = "";
                    }
                }
            },
            computed: {
                label() {
                    return this.open ? "Salir" : "Acceder";
                },
                styles() {
                    return this.open ? ['open'] : ['closed'];
                }
            },
            methods: {
              addnew(){
                this.posts.unshift({
                  title: this.titlepost,
                  description: this.descriptionpost
                })
                this.titlepost = ''
                this.descriptionpost = ''
              },

              deletepost(item){
                this.posts.splice(item, 1);
              }
            },
            template: `
            <div class="container" :class="styles">
                <h2>{{ text }}</h2>
                <div v-if="open">
                    <p>Hola, {{ username }}</p>
                    <div class="formadd">
                      <label>Titulo: </label>
                      <input type="text" v-model="titlepost" /><br/><br/>
                      <label>contenido: </label><br/>
                      <textarea id="" cols="30" rows="5" v-model="descriptionpost"></textarea><br/>
                      <button style="margin-top: 5px;" @click="addnew">add</button><br/>
                    </div>
                    <div class="list">
                        <div v-for="(item, i) in posts" :key="i" class="item">
                            <div style="width:100px;">
                              <div class="title">{{ item.title }}</div>
                              <p>{{ item.description }}</p>
                            </div>
                            <div class="item-button">
                              <button @click="deletepost(i)">eliminar</button>
                            </div>
                        </div>
                    </div>
                </div>
                <div v-else>
                    <div>Username</div>
                    <input type="text" v-model="username" />    
                </div>
                <button @click="open = !open">
                    <div v-if="!open">Acceder</div>
                    <div v-else>Salir</div>
                </button>
            </div>
            `
        }).mount("#app");
    </script>
    <style>
        html, body {
            height: 100vh;
            margin: 0;
            font-family: Arial, Helvetica, sans-serif;
        }
        #app, .container {
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;
            width: 100%;
            height: 100%;
        }
        button {
            margin-top: 24px;
            border: none;
            background-color: white;
            padding: 8px 24px;
            border-radius: 12px;
        }
        .closed {
            background-color: #eca1a6;
        }
        .open {
            background-color: #b5e7a0;
        }
        .list {
            display: flex;
            flex-direction: column;
            margin-top: 10px;
        }
        .item {
            display: flex;
            border: 1px solid black;
        }
        .item-button{
          width: 100%;
          display: flex;
          justify-content: end;
          align-items: center;
        }
        .title {
            font-weight: bold;
            font-size: 1.2rem;
            width: 100%;
        }
        .formadd {
          
        }
    </style>
</body>
</html>

Vue envuelve los métodos de mutación de una matriz observada para que también activen las actualizaciones de vista. Los métodos envueltos son: push(), pop(), shift(), unshift(), splice(), sort(), reverse().

Generalmente los objetos js vienen con un id que identifica cada items:

posts: [
	{
		id: '45',
		title: 'Títlo 1',
		desc: 'Lorem ipsum, dolor sit amet... 1'
	},
	{
		id: '46',
		title: 'Títlo 2',
		desc: 'Lorem ipsum, dolor sit amet... 2'
	},
	{
		id: '47',
		title: 'Títlo 3',
		desc: 'Lorem ipsum, dolor sit amet... 3'
	},
],

La directiva :key también puede tener como identificador el id del objeto, edecir que puede usarse como:

<div v-for="(post, index) in posts" :key="index">

y también como:

<div v-for="post in posts" :key="post.id">

Si quieren agregar un método que adicione un post, lo pueden hacer con .push() por ejemplo, si quieren eliminar un post, pueden suar dos métodos de acuerdo a si lo queremos eliminar por el index o por el id de cada post.

methods: {
    deletePostForIndex(index) {
        if (index >= 0 && index < this.posts.length) {
            this.posts.splice(index, 1);
        } else {
            console.log('No existe el índice');
        }
    },
    deletePostForId(id) {
        const findIndex = this.posts.findIndex((post) => post.id === id);
        if (findIndex >= 0 && findIndex < this.posts.length) {
            this.posts.splice(findIndex, 1);
        } else {
            console.log('No existe el índice');
        }
    },
},