Soy bastante nuevo en Vue.js, gracias por su comprensión. Estoy configurando un proyecto Vue donde quiero mostrar a los pacientes y sus datos. Quiero decir desde el principio que no estoy planeando usar Vuex :)

Mi proyecto tiene 3 capas.

Archivo Home.vue donde importo los datos (pacientes)

La siguiente capa es el componente Patients.vue donde tengo un bucle for y la salida de todos los pacientes. En este caso, estoy obteniendo la matriz de pacientes mediante el uso de accesorios.

Y la última capa se llama vista ViewPatient.vue. Lo que quiero hacer aquí es mostrar más detalles del paciente en el que se ha hecho clic. Quiero heredar, por ejemplo, el nombre para hacer una llamada más al punto final para recuperar algunas observaciones del paciente. Por ejemplo: endpoint/patient/(theName) <-- el nombre debe provenir del componente Patients.vue anterior.

He probado una gran cantidad de enfoques diferentes: bus de eventos, router dinámico y attrbutes de datos.

Home.vue

<template>
  <div class="container">
    <keep-alive>
      <Patients :PatientsData="PatientsData" />
    </keep-alive>
  </div>
</template>

<script>
// @ is an alias to /src
import PatientsData from "../data/messages";
import Patients from "../components/Patients.vue";

export default {
  name: "home",
  data() {
    return {
      PatientsData: PatientsData
    };
  },

  components: {
    Patients
  }
};
</script>

Patients.vue (componente)

<template>
  <div v-if="PatientsData.length > 0">
    <div class="row row-eq-height">
      <div v-for="PatientData in PatientsData" class="col-12 col-sm-6 col-md-3 mb-3" :key="PatientData.content" :data-id="PatientData.content" @click.prevent="passPatientData" >
        <router-link to="/patient" >
          <div class="col-12 patientsTiles p-4">
            <p class="patientsName">
              <span>Navn</span>
              {{ PatientData.content }}
            </p>
            <p class="patientsCPR">
              <span>CPR.nr</span>
              {{ PatientData.subject }}
            </p>
            <p class="patientsAge">
              <span>Alder</span>
              {{PatientData.age}}
            </p>
            <i :class="['fa', 'fa-star', {important: PatientData.isImportant}]"></i>
          </div>
        </router-link>
      </div>
    </div>
  </div>
</template>

<script>
import router from "../main";
import { eventBus } from "../main";
export default {
  props: {
    PatientsData: Array,
  },
  data(){
    return{
      patientName: ""
    }
  },


  methods: {
    passPatientData() {
      this.patientName = this.PatientData;
      alert(this.patientName);

      eventBus.$emit("passPatientData", this.patientName);
    }
  }

};
</script>

ViewPatient.vue (ver)

<template>
  <div class="container">
    <h1>The Patient detail</h1>
  </div>
</template>

<script>
// @ is an alias to /src
import { eventBus } from "../main";

export default {
  props: {
    // patientId:{
    //     type: String
    // } 
  },
  data() {
    return {
      selectedPatient : ""
    };
  },

  created() {  
      eventBus.$on("passPatientData", data  => {  
        this.selectedPatient = data;
        // console.log("yeaah");

 })}
}
</script>

IMO, el problema está en la función passPatientData. éste. PatientData está vacío y no sé cómo pasar los datos del elemento en el que se ha clic a la cadena vacía (this.patientName), por lo que puedo emitirlo al bus de eventos

passPatientData() {
      this.patientName = this.PatientData;
      alert(this.patientName);

      eventBus.$emit("passPatientData", this.patientName);
    }
0
user3374356 5 nov. 2019 a las 00:30

2 respuestas

Has decidido no usar Vuex. Eso no significa que no debas usar una tienda. La tienda más simple es solo un objeto en los datos de su Vue raíz, transmitido a través de provide / inject. Pon tus datos compartidos allí.

Este es un patrón mucho más simple para entenderlo que un autobús de eventos. Obtiene el estado compartido directamente de los componentes de Vue, y debido a que es solo un objeto, que no hace nada más que almacenar el estado, tendrá más control sobre lo que tiene y cómo funciona.

// Home.vue
export default {
    name: "home",
    provide: { mySharedData: this.mySharedData },
    data() {
        return {
            mySharedData: {
                patientData: {}
            }
        };
    },
    created() {
        fetch("http://patientData")
            .then(response.json)
            .then((patientData) => this.mySharedData.patientData = patientData)
    }
    ...

// Then, in all other components of your app...
export default {
        inject: ['mysharedData'],
        ...
    }

De esta manera, estará haciendo pleno uso de la reactividad Vue para propagar sus cambios. Deberá comprender cómo Vue hace que las propiedades sean reactivas. En particular, no puede simplemente asignar nuevos accesorios en mySharedData. La forma más simple es asegurarse de que todos los accesorios estén ahí para comenzar. Para hacerlo sobre la marcha, use Vue.set ().

0
bbsimonbb 4 nov. 2019 a las 22:20

Aquí está mi enfoque que funcionó para mí (pocos cambios):

@bbsimonbb, gracias por la respuesta, pero no voy a usar ese enfoque, porque es un poco exagerado en comparación con mi pequeña tarea.

En Patients.vue mientras looping pacientes, he modificado el evento de clic: En realidad estoy pasando el único elemento que se está haciendo clic, que resolvió med mucho tiempo.

<div v-for="PatientData in storedPatients" class="col-12 col-sm-6 col-md-3 mb-3" :data-id="PatientData.content" @click="passPatientData(PatientData)" >

Antes:

  @click="passPatientData"

Después:

@click="passPatientData(PatientData)"

Y luego en mi bus de eventos im capaz de "trabajar" con los datos im pasando:

methods: {
    passPatientData(element) {
      this.patientName = element.content;
      alert(this.patientName);

      eventBus.$emit("passPatientData", this.patientName);
    }
  }

El propósito es pasar el patientName al archivo ViewPatient.vue mediante el bus de eventos y llamar a un nuevo punto final que tenga este aspecto: endpoint/patient/(patientName) . El resultado del punto final serán los detalles del único paciente en el que se ha hecho clic en patients.vue

Está funcionando. Espero que pueda ser útil para otros que están luchando con el mismo problema.

0
user3374356 5 nov. 2019 a las 10:31