No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Componentes

15/23
Recursos

Aportes 12

Preguntas 3

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

He creado el componente de la siguiente manera:

// Agregando componente, el nombre puede ser en kebab-case o PascalCase
app.component('item-post', {
    // Todos los atributos que debo usar en el componente
    props: ['title', 'desc'],
    // Agregando el template del componente
    template: `
    <div class="item">
        <h3>{{ title }}</h3>
        <p>{{ desc }}</p>
    </div>
    `,
    // Si lo requiere también podemos agregar los propios methods, computed, watch entre otros
});

Y usando el compoente de esta manera:

<div class="list">
    <item-post
        v-for="(item, i) in posts"
        :key="i"
        :title="item.title"
        :desc="item.desc"
    />
</div>

La verdad esta clase se me hizo un poco, bastante confusa

Puedo pensar en 4 componentes en toda la página:

En la pantalla inicial:

  1. Bloque de login

En la pantalla después de iniciar sesión:
2. Header (con username y el botón de logout)
3. Lista de artículos
4. Artículo

¿El botón podría, así mismo, ser un componente por sí mismo?

Modifique el anterior ejemplo de listas, asi lo deje dividiendo el código en algunos componentes

15Componentes.html

esta desde gist, como voy a poner ahi todos los ejemplos del curso cada uno estara en un archivo con el número y nombre del tema o clase

Hola a todos, yo estaba teniendo el siguiente error:

Failed to resolve component: item
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement. 
  at <App> 

Mi error fue declarar app.component después de app.mount. Cambié el orden y se arregló el problema

Excelente clase de componentes!!! Muchas gracias Diana aprendí mucho.

ok, vere que mas codigo puedo poner como componente

Creo que es importante dar más detalles en las clases, aunque sé que este video es viejo, por ejemplo, en el caso del parámetro recibido, quise llamarlo diferente, dado que nos e aclara que se debe llamar post, al llamarlo diferente de inmediato empezó el calvario de ver qué pasaba, dado que creía que era un parámetro normal que recibía el componente, y no es así, debe llamarse post

se pueden extrar los componentes logicos del proyecto, las funciones para multiples usos, los estilos también.

Os dejo aquí mi ejemplo

<script>
      const app = Vue.createApp({
        data() {
          return {
            addPost: {
              title: "",
              description: "",
            },
            add: false,
            openDoor: false,
            posts: [
              {
                title: "Post 1",
                description:
                  "Descripción 1",
              },
              {
                title: "Post 2",
                description:
                  "Descripción 2",
              },
              {
                title: "Post 3",
                description:
                  "Descripción 3",
              },
              {
                title: "Post 4",
                description:
                  "Descripción 4",
              },
            ],
            text: "Inicia sesión",
            userName: "",
          };
        },
        computed: {
          styleComputed2() {
            return this.openDoor ? "open" : "closed";
          },
        },
        watch: {
          openDoor(value, oldValue) {
            if (value) {
              this.text = "Cierra sesión";
            } else {
              this.text = "Inicia sesión";
              this.userName = "";
              this.add = false;
            }
          },
        },
        template: `
            <div class="container" :class="styleComputed2">
              <h2>{{ text }}</h2>
              <div v-if="openDoor">
                <p>Hola, {{ userName }}</p>
                <div class="menuLogin">
                  <button @click="add = true">nuevo</button>
                  <button @click="add = false">ver</button>
                </div>
                <div class="containerAdd" v-if="add">
                  <add
                    :addPost="addPost"
                    :posts="posts"
                  />
                  <div id="divDeletePost">
                    <item
                      class="itemDel"
                      v-for="(item, i) in posts"
                      :key="i"
                      :post="item"
                      :index="i"
                      :posts="posts"
                      :withDescription="false"
                    />
                  </div>
                </div>
                <div v-else class="list">
                  <item
                    v-for="(item, i) in posts"
                    :key="i"
                    :post="item"
                    :index="i"
                    :posts="posts"
                    :withDescription="true"
                  />
                </div>
              </div>
              <div v-else>
                <div>User name </div>
                <input type="text" v-model="userName">
              </div>
              <button class="mgt-24" @click="openDoor = !openDoor">
                <div v-if="!openDoor">Acceder</div>
                <div v-else>Salir</div>
              </button>
            </div>
            `,
      });

      app.component("add", {
        props: ["posts", "addPost"],
        methods: {
          AddPostToTheList() {
            this.posts.push({
              title: this.addPost.title,
              description: this.addPost.description,
            });
          },
        },
        template: `
              <div 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 class="mgt-24"><button @click="AddPostToTheList">Agregar</button></div>
              </div>
            `,
      });

      app.component("item", {
        props: ["post", "index", "posts", "withDescription"],
        methods: {
          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);
          },
        },
        template: `
            <div class="item">
                <div class="title">{{ post.title }}</div>
                <p v-if="withDescription">{{ post.description }}</p>
                <div><button @click="DeletePost(index, post)">borrar</button></div>
            </div>
            `,
      });

      const vm = app.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%;
      }

      .mgt-24 {
        margin-top: 24px;
      }

      button {
        border: none;
        background-color: white;
        padding: 8px 24px;
        border-radius: 12px;
      }

      .addPost {
        background-color: #54964a;
        border: 1px solid #ccc;
        padding: 7px;
      }

      .closed {
        background-color: #eca1a6;
      }

      .containerAdd {
        display: flex;
        flex-direction: row;
        gap: 16px;
        width: 100%;
      }

      .open {
        background-color: #b5e7a0;
      }

      .list {
        display: flex;
        flex-direction: column;
      }

      .item {
        border: 1px solid #1c2263;
        padding: 7px;
        margin-bottom: 7px;
      }

      .itemDel {
        border-bottom: 1px solid #1c2263;
        font-size: 14px;
        margin-bottom: 7px;
      }

      .menuLogin {
        align-items: center;
        display: flex;
        flex-direction: row;
        gap: 7px;
        margin-bottom: 7px;
      }

      .title {
        font-weight: bold;
        font-size: 1.5rem;
      }
    </style>
<script>
        const app = Vue.createApp({
            data(){
                return {
                    text: "sesion",
                    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"
                        }
                    ]
                };
            },
            watch:{
                open(value){
                    if(value){
                        this.text = "Acceder";
                        console.log("true",value)
                        
                    }else{
                        this.text = "Salir";
                        console.log("false",value)
                        this.username = ""
                        
                    }
                }
            },
            computed:{
                label(){
                     return this.open ? "Salir" : "Acceder"
                },
                styles(){
                    return this.open ? ['open'] : ['closed']
                }
            },
            methods: {
                add(){
                    let nuevaData = this.posts.push({
                            title: "Titulo 5",
                            description: "Lorem ipsum 5"
                        })
                    console.log("add")
                },
                delet(index){
                    let nuevaData = this.posts.splice(index)
                    console.log("index",index)
                },
                
            },
            template: ` <div class='container' :class="styles">
                            <h2>{{ text }} </h2>
                            <div v-if="open">
                                <p>hola,{{ username }}</p>
                                <div class="list">
                                    <item 
                                        v-for="(item, i) in posts"
                                        :key="i"
                                        :post="item"
                                        @eliminar="delet(i)"

                                    />
                                </div>
                                <label>Gregar a cola</label>
                                <input type="text" v-model="username">
                                <button @click="add()">add</button>
                                <button @click="delet(index)">delete</button>
                            </div>
                            <div v-else="open">
                                <label>Username</label>
                                <input type="text" v-model="username"> 
                            </div>
                            
                            <button @click="open = !open">
                                <div v-if="!open">Acceder</div>
                                <div v-else >Salir</div>
                            </button>
                            
                        </div>`
        })
        app.component("item", {
            methods:{
                eliminar: function(){
                    this.$emit('eliminar',)
                }
            },
            props: ["post"],
            template:`
            <div class="item">
                <div class="title">{{ post.title }}</div>
                <p>{{ post.description }}</p>
                <button @click="eliminar">delete</button>
            </div>
            `
        } );
        const vm = app.mount("#app")

        
    </script>
Aqui envio algo basico que pude hacer: ```js <script> const vm = Vue.createApp({ data() { return { titulo: '', descripcion: '', entradas: [] }; }, methods: { agregarEntrada() { if (this.titulo.trim() && this.descripcion.trim()) { this.entradas.push({ titulo: this.titulo, descripcion: this.descripcion }); this.titulo = ''; this.descripcion = ''; } else { alert('Por favor, completa ambos campos antes de enviar.'); } }, eliminarEntrada(i) { this.entradas.splice(i, 1); } }, template: `
<form >
<label for="titulo">Título:</label> <input type="text" id="titulo" v-model="titulo" placeholder="Ingresa el título" />
<label for="descripcion">Descripción:</label> <textarea id="descripcion" v-model="descripcion" placeholder="Ingresa la descripción"></textarea>
<button @click.prevent="agregarEntrada" type="submit">Agregar</button> </form>

Entradas:

{{ entrada.titulo }}

{{ entrada.descripcion }}

<button class="btn-delete" @click="eliminarEntrada(i)" type="submit">Eliminar</button>
` }).mount("#app"); </script> <style> body { font-family: Arial, sans-serif; margin: 20px; } form { margin-bottom: 20px; } input, textarea { width: 100%; margin-bottom: 10px; padding: 8px; border: 1px solid #ccc; border-radius: 4px; } button { padding: 10px 20px; background-color: #28a745; color: white; border: none; border-radius: 4px; cursor: pointer; } button:hover { background-color: #218838; } .btn-delete{ background-color: red; } .btn-delete:hover{ background-color: #9c1a33; } </style> ```\<script> const *vm* = Vue.createApp({ data() { return { titulo: '', descripcion: '', entradas: \[] }; }, methods: { agregarEntrada() { if (this.titulo.trim() && this.descripcion.trim()) { this.entradas.push({ titulo: this.titulo, descripcion: this.descripcion }); this.titulo = ''; this.descripcion = ''; } else { alert('Por favor, completa ambos campos antes de enviar.'); } }, eliminarEntrada(i) { this.entradas.splice(i, 1); } }, template: ` \
\<form > \
\<label for="titulo">Título:\</label> \<input type="text" id="titulo" v-model="titulo" placeholder="Ingresa el título" /> \
\
\<label for="descripcion">Descripción:\</label> \<textarea id="descripcion" v-model="descripcion" placeholder="Ingresa la descripción">\</textarea> \
\<button @click.prevent="agregarEntrada" type="submit">Agregar\</button> \</form> \
\

Entradas:\

\
\

{{ entrada.titulo }}\

\

{{ entrada.descripcion }}\

\<button class="btn-delete" @click="eliminarEntrada(i)" type="submit">Eliminar\</button> \
\
\
` }).mount("#app"); \</script> \<style> body { font-family: Arial, sans-serif; margin: 20px; } form { margin-bottom: 20px; } input, textarea { width: 100%; margin-bottom: 10px; padding: 8px; border: 1px solid #ccc; border-radius: 4px; } button { padding: 10px 20px; background-color: #28a745; color: white; border: none; border-radius: 4px; cursor: pointer; } button:hover { background-color: #218838; } .btn-delete{ background-color: red; } .btn-delete:hover{ background-color: #9c1a33; } \</style>