#javascript #vue.js #async.js
#javascript #vue.js #async.js
Вопрос:
привет, я не могу получить доступ к данным реквизита. если я вижу в инструменте разработки Chrome vue, реквизит есть, но я не могу получить доступ к созданному или смонтированному крючку.
ПЕРЕДАЧА РЕКВИЗИТА
<Contradiction
:patient="patient"
@openForm="toggleFormTable">
</Contradiction>
КОМПОНЕНТ ПРОТИВОРЕЧИЯ
name: "Contradiction",
props: {
patient: {
type: Object,
},
},
data() {
return {
patient_id: this.patient.id,
};
},
created() {
console.log("created hook", this.patient); // shows null
},
mounted() {
console.log("mounted hook", this.patient);//shows null
},
Я не знаю, в чем причина, когда я вижу в инструментах разработчика Chrome, что реквизиты пациента есть, но их нет в console.log.
Комментарии:
1. Можете ли вы поделиться рабочей
fiddle
частью своего кода, чтобы его было легко отлаживать?2. Является
patient
ли это каким-то образом асинхронным, например, исходящим из API или подобного? Пробовали ли вы сначала работать с какими — то жестко закодированными данными ? Почти уверен, что здесь как раз такая проблема.3. он поступает из конечной точки api laravel
4. Законно, что он не отображает его на
mounted
крючке жизненного цикла. Его можно заполнить впоследствии, так что это не большая проблема. Но вы не можете ожидать, что у компонента будут данные при монтировании, если вы не дождетесь поступления данных. Вы могли бы создать av-if="Object.entries(patient).length"
дляContradiction
компонента, если хотите. Таким образом, он будет ждать, пока у вас будет объект, а затем смонтирует его.
Ответ №1:
После уточнения из комментария, который patient
не задан непосредственно в родительском компоненте, вы можете определить patient_id
как computed
свойство:
const Contradiction = Vue.component('contradiction', {
template: '#contradiction',
props: { patient: { type: Object } },
computed: {
patient_id() { if(this.patient) return this.patient.id; }
}
});
new Vue({
el: '#app',
components: { Contradiction },
data() { return { patient: null } },
mounted() { setTimeout(() => this.patient = {id:1}, 3000); },
methods: {
toggleFormTable() {}
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div>
<Contradiction :patient="patient" @openForm="toggleFormTable"/>
</div>
</div>
<template id="contradiction">
<div>patient id: {{patient_id}}</div>
</template>
Лучшее решение — сохранить вашу реализацию и отображать дочерний компонент только в том случае, если prop
установлен:
const Contradiction = Vue.component('contradiction', {
template: '#contradiction',
props: { patient: { type: Object } },
data() { return { patient_id: this.patient.id } }
});
new Vue({
el: '#app',
components: { Contradiction },
data() { return { patient: null } },
mounted() { setTimeout(() => this.patient = {id:1}, 3000); },
methods: {
toggleFormTable() {}
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div>
<Contradiction v-if="patient" :patient="patient" @openForm="toggleFormTable"/>
</div>
</div>
<template id="contradiction">
<div>patient id: {{patient_id}}</div>
</template>
Ответ №2:
Вот проект, показывающий вам, как достичь того, чего вы хотите добиться: https://codesandbox.io/s/focused-hugle-3c9cc?file=/src/App.vue
Чтобы подробнее объяснить мой предыдущий комментарий, мы используем v-if="Object.entries(patient).length"
, чтобы убедиться, что данные здесь, прежде чем загружать что-либо вообще.
<contradiction
v-if="Object.entries(patient).length"
:patient="patient"
></contradiction>
Ленивая загрузка компонента также полезна с точки зрения производительности:
components: {
Contradiction: () => import("./components/contradiction"),
},