Estoy probando provide and inject método. Puse datas , del-function en parent para proporcionar, puse renderizado dinámico en child usando v-for='data' in datas ...
El objetivo que quiero implementar es: cuando presiono el "botón eliminar" => del-function del elemento secundario, los datas en el elemento principal obtienen un elemento eliminado y provide datas en el elemento principal se actualizan.
datas para hacer una actualización visual. v-for volver a renderizar. [!!!] Pero cuando presiono el "botón eliminar", los datas se actualizan, pero visualmente, nadie se elimina.
// parent vue file <template> <Reslist/> </template> <script> import Reslist from './components/ResList.vue' export default { name: "App", components: { Reslist }, provide() { return { datas: this.datas, delData: this.delData, }; }, data() { return { datas: [ { id: 1, name: "wawa", age: "18", }, { id: 2, name: "wmmmfwa", age: "1128", }, ], }; }, methods: { delData(id) { console.log('delete-id ='+ id); const newDatas = this.datas.filter( element => element.id !== id); this.datas = newDatas; console.log( this.datas); }, }, }; </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style> // child vue file <template> <div v-for='data in datas' :key="data.name"> <h2>{{data.name}}</h2> <p>{{data.age}}</p> <button @click='delData(data.id)'>delete</button> </div> </template> <script> export default { inject:['datas','delData'] } </script> <style scoped> div{ width: 18.75rem; margin: 1.25rem auto; border: solid 1px grey; padding: 1.25rem; } </style>Sé cómo usar prop para pasar datos al niño. Solo quiero saber por qué [proporcionar e inyectar] no funcionan. En [provide], ya [datas = this.datas], ¿mi lógica tiene errores?
Los datos inyectados no funcionan de manera reactiva y, según la Documentación de Vue.js , para que los datos inyectados hagan esto, debe proporcionarlos como una propiedad computada envolviéndolos en una función computed() :
Que estados:
Trabajando con Reactividad
Para realizar inyecciones vinculadas de forma reactiva al proveedor, debemos proporcionar una propiedad calculada mediante la función computed()
En tu caso, podría verse así:
provide() { return { datas: computed(() => this.datas), delData: this.delData, }; },Habiendo dicho esto, Vue siempre está experimentando actualizaciones, mejoras y correcciones, y para que esto funcione completamente, temporalmente , debe agregar una configuración adicional a su aplicación:
Que estados:
Configuración temporal requerida
El uso anterior requiere configurar
app.config.unwrapInjectedRef = truepara que las inyecciones desenvuelvan automáticamente las referencias calculadas. Este se convertirá en el comportamiento predeterminado en Vue 3.3 y esta configuración se introduce temporalmente para evitar roturas. Ya no será necesario después de 3.3.
En código, esto podría verse así:
import { createApp } from 'vue' import App from './App.vue' import './index.css' const app = createApp(App); app.config.unwrapInjectedRef = true; app.mount('#app')¡Buenas noches hermano!
Encontré una solución usando accesorios computados ...
¡Espero que sea útil!
Archivo principal de Vue
<template> <Reslist/> </template> <script> import Reslist from './ResList.vue' import { computed } from '@vue/reactivity' export default { name: "App", components: { Reslist }, provide() { return { datas: computed(() => this.datas), delData: this.delData, }; }, data() { return { datas: [ { id: 1, name: "wawa", age: "18", }, { id: 2, name: "wmmmfwa", age: "1128", }, ], }; }, methods: { delData(id) { console.log('delete-id ='+ id); const newDatas = this.datas.filter( element => element.id !== id); this.datas = newDatas; console.log(this.datas); }, }, }; </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>Archivo de niño
<template> <div v-for='data in datas' :key="data.name"> <h2>{{data.name}}</h2> <p>{{data.age}}</p> <button @click='delData(data.id)'>delete</button> </div> </template> <script> export default { inject:['datas','delData'] } </script> <style scoped> div{ width: 18.75rem; margin: 1.25rem auto; border: solid 1px grey; padding: 1.25rem; } </style>Configuración de Main.js para aceptar prop computado.
import { createApp } from 'vue' import App from './App.vue' const app = createApp(App) app.config.unwrapInjectedRef = true app.mount('#app')La información para esta configuración: https://vuejs.org/guide/components/provide-inject.html#working-with-reactivity