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');
        }
    },
},