Cómo crear un cargador de archivos de arrastrar y soltar con Vue.js 3

 

 

 

  • Implemente rápidamente. Implementar inteligentemente
  • SmashingConf Nueva York 2024

  • Índice
    1. Configuración
    2. Zona de descenso
      1. Estado activo
    3. Administrador de lista de archivos
      1. Posibles mejoras
    4. Mejor juntos
    5. Vista previa de imágenes seleccionadas

    Sobre la base de un artículo anterior sobre Cómo crear un cargador de archivos de arrastrar y soltar , agregaremos algunas características nuevas, pero lo más importante (tal vez) aprenderemos cómo construirlo en Vue 3 y aprenderemos algunas de las mejores. prácticas para Vue a lo largo del ceroso.

     

    ¿Qué diferencia al cargador de archivos que estamos creando en este artículo respecto al anterior? El anterior cargador de archivos de arrastrar y soltar se creó con Vanilla JS y realmente se centró en cómo hacer que la carga de archivos y la selección de archivos de arrastrar y soltar funcionen, por lo que su conjunto de funciones era limitado. Subió los archivos inmediatamente después de que los elegiste con una barra de progreso simple y una vista previa en miniatura de la imagen. Puedes ver todo esto en esta demostración .

    Además de usar Vue, cambiaremos las funciones: después de agregar una imagen, no se cargará inmediatamente. En su lugar, aparecerá una vista previa en miniatura. Habrá un botón en la parte superior derecha de la miniatura que eliminará el archivo de la lista en caso de que no haya querido seleccionar una imagen o haya cambiado de opinión acerca de cargarla.

    Luego hará clic en el botón "Cargar" para enviar los datos de la imagen al servidor y cada imagen mostrará su estado de carga. Para colmo, creé algunos estilos elegantes (aunque no soy diseñador, así que no juzgues demasiado duramente). No profundizaremos en esos estilos en este tutorial, pero estarán disponibles para que los copie o examine usted mismo en el Repositorio de GitHub ; sin embargo, si va a copiarlos, asegúrese de configurar su proyecto. para poder usar estilos Stylus (o puede configurarlo para usar Sass y cambiar langa scsslos bloques de estilo y funcionará de esa manera). También puede ver lo que estamos creando hoy en la página de demostración .

    Nota : Asumiré que los lectores tienen un sólido conocimiento de JavaScript y una buena comprensión de las funciones y API de Vue, especialmente la API de composición de Vue 3, pero no necesariamente las mejores formas de usarlas. Este artículo tiene como objetivo aprender cómo crear un cargador de arrastrar y soltar en el contexto de una aplicación Vue mientras analiza buenos patrones y prácticas y no profundizará en cómo usar Vue en sí.

     

    Configuración

    Hay muchas formas de configurar un proyecto Vue: Vue CLI , Vite , Nuxt y Quasar tienen sus propias herramientas de andamiaje de proyectos, y estoy seguro de que hay más. No estoy muy familiarizado con la mayoría de ellas y no voy a prescribir ninguna herramienta específica para este proyecto, por lo que recomiendo leer la documentación de la que elijas para descubrir cómo configurar la forma en que Lo necesito para este pequeño proyecto.

    Necesitamos estar configurados con Vue 3 con la sintaxis de configuración del script , y si estás tomando mis estilos del repositorio de Github , necesitarás asegurarte de que estás configurado para compilar tus estilos de Vue desde Stylus (o puedes configurarlo para usar Sass y cambiar langa “scss” para los bloques de estilo y funcionará de esa manera).

    Zona de descenso

    Ahora que tenemos el proyecto configurado, profundicemos en el código. Comenzaremos con un componente que maneja la funcionalidad de arrastrar y soltar. Este será un divelemento contenedor simple con un montón de detectores y emisores de eventos en su mayor parte. Este tipo de elemento es un gran candidato para un componente reutilizable (a pesar de que solo se usa una vez en este proyecto en particular): tiene un trabajo muy específico que hacer y ese trabajo es lo suficientemente genérico como para usarse de muchas maneras o lugares diferentes. sin la necesidad de un montón de opciones de personalización o complejidad.

    Esta es una de esas cosas a las que los buenos desarrolladores siempre están atentos. Reunir una gran cantidad de funciones en un solo componente sería una mala idea para este proyecto o cualquier otro porque entonces 1) no se puede reutilizar si encuentra una situación similar más adelante y 2) es más difícil ordenar el código y la figura. descubrir cómo se relaciona cada pieza entre sí. Entonces, haremos lo que podamos para seguir este principio y comienza aquí con el DropZonecomponente. Comenzaremos con una versión simple del componente y luego lo arreglaremos un poco para ayudarlo a asimilar lo que está sucediendo un poco más fácilmente, así que creemos un DropZone.vuearchivo en la src/componentscarpeta:

    template div @drop.prevent="onDrop" slot/slot /div/templatescript setupimport { onMounted, onUnmounted } from 'vue'const emit = defineEmits(['files-dropped'])function onDrop(e) { emit('files-dropped', [...e.dataTransfer.files])}function preventDefaults(e) { e.preventDefault()}const events = ['dragenter', 'dragover', 'dragleave', 'drop']onMounted(() = { events.forEach((eventName) = { document.body.addEventListener(eventName, preventDefaults) })})onUnmounted(() = { events.forEach((eventName) = { document.body.removeEventListener(eventName, preventDefaults) })})/script

    Primero, mirando la plantilla, verá un divcontrolador dropde eventos (con un preventmodificador para evitar acciones predeterminadas) que llama a una función a la que llegaremos en un momento. Dentro divhay un slot, por lo que podemos reutilizar este componente con contenido personalizado en su interior. Luego llegamos al código JavaScript, que está dentro de una scriptetiqueta con el setupatributo.

     

    Nota : Si no está familiarizado con los beneficios que obtenemos de este atributo y no leyó el enlace que agregamos anteriormente, diríjase a la documentación script setup para componentes de un solo archivo .

    Dentro del script, definimos un evento que emitiremos llamado "archivos eliminados" que otros componentes pueden usar para hacer algo con los archivos que se eliminan aquí. Luego definimos la función onDroppara manejar el evento de caída. En este momento, todo lo que hace es emitir el evento que acabamos de definir y agregar una matriz de archivos que acabamos de eliminar como carga útil. Tenga en cuenta que estamos usando un truco con el operador de extensión para convertir la lista de archivos FileListque e.dataTransfer.filesnos proporciona en una matriz de Files para que la parte del sistema que toma los archivos pueda invocar todos los métodos de la matriz.

    Finalmente, llegamos al lugar donde manejamos los otros eventos de arrastrar y soltar que ocurren en el cuerpo, evitando el comportamiento predeterminado durante el proceso de arrastrar y soltar (es decir, que abrirá uno de los archivos en el navegador. Creamos una función eso simplemente llama preventDefaultal objeto de evento. Luego, en el onMountedgancho del ciclo de vida iteramos sobre la lista de eventos y evitamos el comportamiento predeterminado para eso incluso en el cuerpo del documento. En el onUnmountedgancho, eliminamos esos oyentes.

    Estado activo

    Entonces, ¿qué funcionalidad extra podemos añadir? Lo único que decidí agregar fue algún estado que indicara si la zona de colocación estaba "activa", lo que significa que un archivo se encuentra actualmente sobre la zona de colocación. Eso es bastante simple; cree un refllamado active, configúrelo en verdadero en los eventos cuando los archivos se arrastran sobre la zona de colocación y en falso cuando abandonan la zona o se sueltan.

    También queremos exponer este estado a los componentes usando DropZone, por lo que convertiremos nuestro sloten una ranura con alcance y expondremos ese estado allí. En lugar de la ranura con alcance (o además de ella para mayor flexibilidad), podríamos emitir un evento para informar al exterior del valor de activea medida que cambia. La ventaja de esto es que todo el componente que se utiliza DropZonepuede tener acceso al estado, en lugar de limitarse a los componentes/elementos dentro de la ranura de la plantilla. Sin embargo, nos quedaremos con el espacio específico para este artículo.

     

    Finalmente, por si acaso, agregaremos un data-activeatributo que refleje activeel valor de para que podamos eliminarlo para darle estilo. También puedes usar una clase si lo prefieres, pero a mí me gustan los atributos de datos para los modificadores de estado.

    Escribámoslo:

    template !-- add `data-active` and the event listeners -- div :data-active="active" @dragenter.prevent="setActive" @dragover.prevent="setActive" @dragleave.prevent="setInactive" @drop.prevent="onDrop" !-- share state with the scoped slot -- slot :dropZoneActive="active"/slot /div/templatescript setup// make sure to import `ref` from Vueimport { ref, onMounted, onUnmounted } from 'vue'const emit = defineEmits(['files-dropped'])// Create `active` state and manage it with functionslet active = ref(false)function setActive() { active.value = true}function setInactive() { active.value = false}function onDrop(e) { setInactive() // add this line too emit('files-dropped', [...e.dataTransfer.files])}// ... nothing changed below this/script

    Agregué algunos comentarios en el código para señalar dónde estaban los cambios, así que no profundizaré demasiado en ello, pero tengo algunas notas. Estamos usando los preventmodificadores en todos los detectores de eventos nuevamente para asegurarnos de que el comportamiento predeterminado no se active. Además, notarás que las funciones setActivey setInactiveparecen un poco exageradas ya que podrías configurarlas activedirectamente y podrías presentar ese argumento con seguridad, pero espera un poco; Habrá otro cambio que realmente justifica la creación de funciones.

    Verás, hay un problema con lo que hemos hecho. Como puede ver en el video a continuación, usar este código para la zona de colocación significa que puede parpadear entre estados activo e inactivo mientras arrastra algo dentro de la zona de colocación.

    Por qué esta haciendo eso? Cuando arrastra algo sobre un elemento secundario, "entrará" en ese elemento y "saldrá" de la zona de colocación, lo que hará que quede inactivo. El dragenterevento llegará a la zona de lanzamiento, pero sucede antes del dragleaveevento, por lo que eso no ayuda. Luego, se activará nuevamente un dragoverevento en la zona de caída que la volverá a activar, no sin antes parpadear al estado inactivo.

    Para solucionar este problema, agregaremos un breve tiempo de espera a la setInactivefunción para evitar que quede inactiva inmediatamente. Luego setActivese borrará ese tiempo de espera para que, si se llama antes de que lo establezcamos como inactivo, en realidad no quede inactivo. Hagamos esos cambios:

    // Nothing changed abovelet active = ref(false)let inActiveTimeout = null // add a variable to hold the timeout keyfunction setActive() { active.value = true clearTimeout(inActiveTimeout) // clear the timeout}function setInactive() { // wrap it in a `setTimeout` inActiveTimeout = setTimeout(() = { active.value = false }, 50)}// Nothing below this changes

    Notarás un tiempo de espera de 50 milisegundos. ¿Por qué este número? Porque he probado varios tiempos de espera diferentes y este me parece el mejor.

     

    Sé que es subjetivo, pero escúchame. Probé tiempos de espera mucho más pequeños y 15 ms fue lo más bajo posible donde nunca vi un parpadeo, pero ¿quién sabe cómo funcionará eso en otro hardware? En mi opinión, tiene un margen de error demasiado pequeño. Probablemente tampoco quieras pasar más de 100 ms porque eso puede causar un retraso percibido cuando un usuario hace algo intencionalmente que debería causar que quede inactivo. Al final, me instalé en algún punto intermedio que es lo suficientemente largo como para garantizar que no habrá ningún parpadeo en ningún hardware y que no se percibirá ningún retraso.

    Eso es todo lo que necesitamos para el DropZonecomponente, así que pasemos a la siguiente pieza del rompecabezas: un administrador de listas de archivos.

    Administrador de lista de archivos

    Supongo que lo primero que hay que hacer es una explicación de lo que quiero decir con administrador de listas de archivos. Esta será una función de composición que devolverá varios métodos para administrar el estado de los archivos que el usuario intenta cargar. Esto también podría implementarse como una tienda Vuex / Pinia / alternativa , pero para mantener las cosas simples y evitar la necesidad de instalar una dependencia si no la necesitamos, tiene mucho sentido mantenerla como una función de composición. especialmente porque no es probable que los datos se necesiten ampliamente en toda la aplicación, que es donde las tiendas son más útiles.

    También podría simplemente crear la funcionalidad directamente en el componente que utilizará nuestro DropZonecomponente, pero esta funcionalidad parece algo que podría reutilizarse muy fácilmente; sacarlo del componente hace que sea más fácil para el componente comprender la intención de lo que está sucediendo (asumiendo buenos nombres de funciones y variables) sin necesidad de recorrer toda la implementación.

    Ahora que hemos dejado claro que esta será una función de composición y por qué, esto es lo que hará el administrador de listas de archivos:

    1. Mantener una lista de archivos que han sido seleccionados por el usuario;
    2. Evite archivos duplicados;
    3. Permítanos eliminar archivos de la lista;
    4. Aumente los archivos con metadatos útiles: una identificación, una URL que se puede usar para mostrar una vista previa del archivo y el estado de carga del archivo.

    Entonces, vamos a construirlo en src/compositions/file-list.js: Cursos gratis en Youtube

    import { ref } from 'vue'export default function () { const files = ref([]) function addFiles(newFiles) { let newUploadableFiles = [...newFiles] .map((file) = new UploadableFile(file)) .filter((file) = !fileExists(file.id)) files.value = files.value.concat(newUploadableFiles) } function fileExists(otherId) { return files.value.some(({ id }) = id === otherId) } function removeFile(file) { const index = files.value.indexOf(file) if (index -1) files.value.splice(index, 1) } return { files, addFiles, removeFile }}class UploadableFile { constructor(file) { this.file = file this.id = `${file.name}-${file.size}-${file.lastModified}-${file.type}` this.url = URL.createObjectURL(file) this.status = null }}

    Estamos exportando una función de forma predeterminada que devuelve la lista de archivos (como ref) y un par de métodos que se utilizan para agregar y eliminar archivos de la lista. Sería bueno hacer que la lista de archivos se devuelva como de solo lectura para obligarlo a usar los métodos para manipular la lista, lo cual puede hacer con bastante facilidad usando la readonlyfunción importada de Vue, pero eso causaría problemas con el cargador que usamos. Construiremos más tarde.

     

    Tenga en cuenta que filestiene como ámbito la función de composición y se establece dentro de ella, por lo que cada vez que llame a la función, recibirá una nueva lista de archivos. Si desea compartir el estado entre varios componentes/llamadas, deberá extraer esa declaración de la función para que tenga un alcance y se establezca una vez en el módulo, pero en nuestro caso solo la usaremos una vez, por lo que En realidad no importa, y estaba trabajando pensando que cada instancia de la lista de archivos sería utilizada por un cargador separado y que cualquier estado se puede transmitir a los componentes secundarios en lugar de compartirse a través de la función de composición.

    La parte más compleja de este administrador de listas de archivos es agregar nuevos archivos a la lista. Primero, nos aseguramos de que si se FileListpasó un objeto en lugar de una matriz de Fileobjetos, luego lo convertimos en una matriz (como lo hicimos cuando DropZoneemitimos los archivos. Esto significa que probablemente podríamos omitir esa transformación, pero mejor prevenir que curar). Luego convertimos el archivo a UploadableFile, que es una clase que estamos definiendo y que envuelve el archivo y nos brinda algunas propiedades adicionales. Estamos generando un idarchivo basado en varios aspectos para que podamos detectar duplicados, una blob://URL de la imagen para que podamos mostrar miniaturas de vista previa y un estado para rastrear las cargas.

    Ahora que tenemos los ID de los archivos, filtramos los archivos que ya existen en la lista de archivos antes de concatenarlos al final de la lista de archivos.

    Posibles mejoras

    Si bien este administrador de listas de archivos funciona bien para lo que hace, se pueden realizar varias actualizaciones. Por un lado, en lugar de empaquetar el archivo en una nueva clase y luego tener que llamarlo .filepara acceder al objeto de archivo original, podríamos empaquetar el archivo en un proxy que especifique nuestras nuevas propiedades, pero luego reenviaremos cualquier otra solicitud de propiedad a al objeto original, por lo que es más fluido.

    Como alternativa a empaquetar cada archivo en un archivo UploadableFile, podríamos haber proporcionado funciones de utilidad que podrían devolver el ID o la URL dado un archivo, pero eso es un poco menos conveniente y significaría que potencialmente estarías calculando estas propiedades varias veces (para cada renderizado, y así sucesivamente), pero eso realmente no debería importar a menos que estés tratando con personas que lanzan miles de imágenes a la vez, en cuyo caso puedes intentar memorizarlas.

     

    En cuanto al estado, no se extrae directamente del archivo File, por lo que una función de utilidad simple como las demás no sería posible, pero podrías almacenar el estado de cada archivo con el cargador (lo crearemos más adelante). que directamente con los archivos. Esta podría ser una mejor manera de manejarlo en una aplicación grande para que no terminemos llenando la UploadableFileclase con un montón de propiedades que solo facilitan un área única de la aplicación y son inútiles en otras partes.

    Nota : Para nuestros propósitos, tener las propiedades disponibles directamente en nuestro objeto de archivo es, con diferencia, lo más conveniente, pero definitivamente se puede argumentar que no es lo más apropiado.

    Otra posible mejora es permitirle especificar un filtro para que solo permita agregar ciertos tipos de archivos a la lista. Esto también requeriría addFilesdevolver errores cuando algunos archivos no coincidan con el filtro para que el usuario sepa que cometió un error. Definitivamente, esto es algo que debería hacerse en aplicaciones listas para producción.

    Mejor juntos

    Estamos lejos de tener un producto terminado, pero juntemos las piezas que tenemos para verificar que todo esté funcionando hasta ahora. Vamos a editar el /src/App.vuearchivo para colocar estas piezas, pero puedes agregarlas a cualquier componente de página/sección que desees. Sin embargo, si lo coloca dentro de un componente alternativo, ignore cualquier cosa (como el ID de "aplicación") que solo se vería en el componente principal de la aplicación.

    template div DropZone @files-dropped="addFiles" #default="{ dropZoneActive }" div v-if="dropZoneActive" divDrop Them/div /div div v-else divDrag Your Files Here/div /div /DropZone /div/templatescript setupimport useFileList from './compositions/file-list'import DropZone from './components/DropZone.vue'const { files, addFiles, removeFile } = useFileList()/script

    Si comienzas con la scriptsección, verás que no estamos haciendo mucho. Estamos importando los dos archivos que acabamos de terminar de escribir y estamos inicializando la lista de archivos. Tenga en cuenta que no los estamos usando fileso removeFiletodavía, pero lo haremos más adelante, así que los mantendré allí por ahora. Lo siento si ESLint se queja de variables no utilizadas. Querremos filesal menos para poder ver si funciona más tarde.

    Pasando a la plantilla, puede ver que estamos usando el DropZonecomponente de inmediato. Le estamos dando una clase para que podamos diseñarlo, pasando la addFilesfunción para el controlador de eventos "archivos descartados" y tomando la variable de ranura con alcance para que nuestro contenido pueda ser dinámico en función de si la zona de colocación está activa o no. Luego, dentro de la ranura de la zona de colocación, creamos un divmensaje que muestra un mensaje para arrastrar archivos si está inactivo y un mensaje para soltarlos cuando está activo.

    Ahora, probablemente querrás algunos estilos para al menos hacer que la zona de colocación sea más grande y más fácil de encontrar. No pegaré ninguno aquí, pero puedes encontrar los estilos que usé App.vueen el repositorio .

     

    Ahora, antes de que podamos probar el estado actual de la aplicación, necesitaremos la versión beta de Vue DevTools instalada en nuestro navegador (la versión estable aún no es compatible con Vue 3). Puede obtener Vue DevTools en la tienda web de Chrome para la mayoría de los navegadores basados ​​en Chromium o descargar Vue DevTools aquí para Firefox .

    Después de haberlo instalado, ejecute su aplicación con npm run serve(Vue CLI), npm run dev(Vite) o cualquier script que use en su aplicación, luego ábrala en su navegador a través de la URL proporcionada en la línea de comando. Abra Vue DevTools, luego arrastre y suelte algunas imágenes en la zona de colocación. Si funcionó, debería ver una serie de todos los archivos que agregó cuando vea el componente que acabamos de escribir (vea la captura de pantalla a continuación).

    Vue DevTools mostrando los archivos que agregamos. ( Vista previa grande )

    ¡Lindo! Ahora hagamos esto un poco más accesible para los usuarios que no pueden (o no quieren) arrastrar y soltar, agregando una entrada de archivo oculta (que se vuelve visible cuando se enfoca a través del teclado para aquellos que la necesitan, suponiendo que esté usando mis estilos) y envolviendo una gran etiqueta alrededor de todo para permitirnos usarlo a pesar de su invisibilidad. Finalmente, necesitaremos agregar un detector de eventos a la entrada del archivo para que cuando un usuario seleccione un archivo, podamos agregarlo a nuestra lista de archivos.

    Comencemos con los cambios en la scriptsección. Simplemente vamos a agregar una función al final:

    function onInputChange(e) { addFiles(e.target.files) e.target.value = null}

    Esta función maneja el evento de "cambio" activado desde la entrada y agrega los archivos de la entrada a la lista de archivos. Tenga en cuenta la última línea de la función que restablece el valor de la entrada. Si un usuario agrega un archivo a través de la entrada, decide eliminarlo de nuestra lista de archivos, luego cambia de opinión y decide usar la entrada para agregar ese archivo nuevamente, entonces la entrada del archivo no activará el evento de "cambio" porque el archivo la entrada no ha cambiado. Al restablecer el valor de esta manera, nos aseguramos de que el evento siempre se active.

    Ahora, hagamos nuestros cambios en la plantilla. Cambie todo el código dentro de la DropZoneranura a lo siguiente:

    label for="file-input" span v-if="dropZoneActive" spanDrop Them Here/span spanto add them/span /span span v-else spanDrag Your Files Here/span span or strongemclick here/em/strong to select files /span /span input type="file" multiple @change="onInputChange" //label

    Envolvemos todo en una etiqueta que está vinculada a la entrada del archivo, luego volvemos a agregar nuestros mensajes dinámicos, aunque agregué un poco más de mensajes para informar a los usuarios que pueden hacer clic para seleccionar archivos. También agregué un poco para el mensaje "soltarlos" para que tengan la misma cantidad de líneas de texto para que la zona de colocación no cambie de tamaño cuando esté activa. Finalmente, agregamos la entrada del archivo, configuramos el multipleatributo para permitir a los usuarios seleccionar varios archivos a la vez y luego conectamos el detector de eventos "cambio" a la función que acabamos de escribir.

     

    Ejecute la aplicación nuevamente, si la detuvo, deberíamos ver el mismo resultado en Vue DevTools ya sea que arrastremos y soltemos archivos o hagamos clic en el cuadro para usar el selector de archivos.

    Vista previa de imágenes seleccionadas

    Genial, pero los usuarios no usarán Vue DevTools para ver si los archivos que soltaron realmente se agregaron, así que comencemos a mostrarles esos archivos a los usuarios. Comenzaremos simplemente editando App.vue(o cualquier archivo componente al que haya agregado DropZone) y mostrando una lista de texto simple con los nombres de los archivos.

    Agreguemos el siguiente fragmento de código a la plantilla inmediatamente después del que labelacabamos de agregar en el paso anterior:

    ul v-show="files.length" li v-for="file of files" :key="file.id"{{ file.file.name }}/li/ul

    Ahora, con la aplicación ejecutándose, si agrega algunos archivos a la lista, debería ver una lista con viñetas de los nombres de los archivos. Si copiaste mis estilos, puede que parezca un poco extraño, pero está bien porque lo cambiaremos pronto. Tenga en cuenta que gracias a agregar el ID del archivo en el administrador de la lista de archivos, ahora tenemos una clave en el bucle. Lo único que me molesta personalmente es que, dado que empaquetamos los archivos, necesitamos escribir file.filepara acceder al objeto del archivo original para obtener su nombre. Al final, sin embargo, es un pequeño sacrificio.

    Ahora, comencemos a mostrar las imágenes en lugar de simplemente enumerar sus nombres, pero es hora de sacar esta funcionalidad de este componente principal. Ciertamente podríamos seguir poniendo la función de vista previa de archivos aquí, pero hay dos buenas razones para eliminarla:

    1. La funcionalidad es potencialmente reutilizable en otros casos.
    2. A medida que esta funcionalidad se expande, separarla evita que el componente principal se hinche demasiado.

    Entonces, creemos /src/FilePreview.vuepara incluir esta funcionalidad y comenzaremos mostrando la imagen en un contenedor.

    template component :is="tag" img :src="file.url" :alt="file.file.name" :title="file.file.name" / /component/templatescript setupdefineProps({ file: { type: Object, required: true }, tag: { type: String, default: 'li' },})/script

    Una vez más, los estilos no están incluidos aquí, pero puedes encontrarlos en GitHub . Sin embargo, lo primero que debemos tener en cuenta sobre el código que tenemos es que lo envolvemos en una componentetiqueta y configuramos qué tipo de etiqueta es con un tagaccesorio. Esta puede ser una buena manera de hacer que un componente sea más genérico y reutilizable. Actualmente estamos usando esto dentro de una lista desordenada, por lo que lies la opción obvia, pero si queremos usar este componente en otro lugar en algún momento, es posible que no esté en una lista, por lo que querríamos una etiqueta diferente.

    Para la imagen, usamos la URL creada por el administrador de la lista de archivos y usamos el nombre del archivo como texto alternativo y como titleatributo para obtener esa funcionalidad gratuita de que los usuarios puedan pasar el cursor sobre la imagen y ver el nombre del archivo como información sobre herramientas. Por supuesto, siempre puedes crear tu propia vista previa del archivo donde se escribe el nombre del archivo y siempre está visible para el usuario. Ciertamente hay mucha libertad en cómo se puede manejar esto.

    Pasando a JavaScript, vemos accesorios definidos para que podamos pasar el archivo que estamos obteniendo una vista previa y un nombre de etiqueta para personalizar el contenedor y hacerlo utilizable en más situaciones.

    Por supuesto, si intenta ejecutar






    Tal vez te puede interesar:

    1. ¿Deberían abrirse los enlaces en ventanas nuevas?
    2. 24 excelentes tutoriales de AJAX
    3. 70 técnicas nuevas y útiles de AJAX y JavaScript
    4. Más de 45 excelentes recursos y repositorios de fragmentos de código

    Cómo crear un cargador de archivos de arrastrar y soltar con Vue.js 3

    Cómo crear un cargador de archivos de arrastrar y soltar con Vue.js 3

    Implemente rápidamente. Implementar inteligentemente SmashingConf Nueva York 2024 Índice Configuración

    programar

    es

    https://pseint.es/static/images/programar-como-crear-un-cargador-de-archivos-de-arrastrar-y-soltar-con-vue-1133-0.jpg

    2024-04-04

     

    Cómo crear un cargador de archivos de arrastrar y soltar con Vue.js 3
    Cómo crear un cargador de archivos de arrastrar y soltar con Vue.js 3

    Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

     

     

    Top 20