Vue ожидание данных от реквизита перед использованием - PullRequest
1 голос
/ 22 января 2020

Я продолжаю сталкиваться с проблемой, когда я жду данных от опоры, чтобы сделать что-то внутри нее в моем созданном хуке. Он продолжает выдавать ошибки, такие как «this.value не определено» (поскольку он еще не загружен из prop)

Я исправил некоторые из этих проблем, используя v-if и используя только при необходимости. Однако в некоторых случаях я хотел использовать эту информацию в моем созданном, и когда это происходит, я получаю ошибки и не уверен, как лучше сказать этой части созданного «ждать» данных перед запуском.

Любой совет?

-

Обновление, чтобы добавить пример кода.

На странице приложения. js, я вызов в "userInfo" и установка его в данных, например, так. Я делаю это по двум причинам. Во-первых, чтобы проверить, вошел ли пользователь в систему, а во-вторых, нашли время, чтобы сохранить информацию о пользователях, поскольку она будет использоваться позже во всем приложении. (Обратите внимание, что user и userInfo различаются и содержат разную информацию. Пользователь - это электронная почта / пароль, а userInfo - имя пользователя, биография и т. Д. c.)

data() {
  return {
    user: null,
    userInfo: null,
  }
},
created(){
//let user = firebase.auth().currentUser
  firebase.auth().onAuthStateChanged((user) => {
    if(user){
      this.user = user
      let ref = db.collection('users')
      .where('user_id', '==', this.user.uid)
      ref.get().then(snapshot => {
      snapshot.forEach(doc => {
        this.userInfo = doc.data()
      })
    })

    } else {
      this.user = null
    }
  })
},

Теперь я передаю эту информацию в используя V-Bind. и затем вызывать его в тех областях, где мне нужна информация, используя реквизит.

Проблема возникает, когда я хочу сделать что-то, например -

if(this.userInfo) {
  value = true  
}

Вызов this.userInfo выдает ошибку «this». userInfo is null "(я установил его в null в data () страницы по умолчанию).

Ответы [ 3 ]

1 голос
/ 22 января 2020

Как уже упоминалось в комментариях, вы столкнулись с проблемой решения Promise. При передаче результата в виде проп, который разрешается обещанием, этот результат будет в основном пустым, что в конечном итоге приведет к ошибке в вашем хуке дочерних компонентов created().

Я бы порекомендовал использовать v-if в качестве вы уже сделали в самом дочернем компоненте. Однако я бы использовал v-if в родительском компоненте, чтобы просто показать / скрыть дочерний элемент. Это должно не только решить проблему в вашей created() ловушке, но и помочь создать более читаемую разметку в вашем дочернем компоненте, где вы можете просто удалить все v-if s.

Итак, давайте предположим, что у вас есть Подобные отношения между родителями и детьми.

<SomeParentComponent>
  <SomeChildComponent :someProp="yourProp" />
</SomeParentComponent>

Если после разрешающего обещания установлено значение yourProp, начальное значение будет null, undefined или любое другое значение, установленное вами. Чтобы не пропускать пустую подпорку, вы можете просто обернуть в v-if, выражение которого равно yourProp точно так же.

<SomeParentComponent>
  <SomeChildComponent :someProp="yourProp" v-if="yourProp" />
</SomeParentComponent>                           <!-- ^-- See here -->

При этом Child будет отображаться только тогда, когда yourProp установлено, и поэтому вы больше не получите никаких ошибок.

1 голос
/ 22 января 2020

Я могу придумать как минимум два подхода:

1. Внедрение зависимостей

Родитель / root в provide данные / объект вниз по дереву компонентов и принимающему концу (потомкам) в inject их.

Parent

{
  data: () => ({
    userInfo: null
  }),

  created() {
    // Populates data via Firebase 
    // Code omitted for brevity...

    this.userInfo = doc.data();
  },

  provide() {
    return Object.defineProperty({}, 'userInfo', {
      get: () => this.userInfo
    })
  }
}

Дети

// Children
{
  inject: ['userInfo'],

  created() {
    if (this.userInfo) {
      // Do something 
    }
  },
  mounted() {
    if (this.userInfo) {
      // Do something 
    }
  },
  // Any lifecycle hooks, methods or virtually anywhere needing a reference to this object
}

2. Vuex store

Вместо того, чтобы передавать реквизит и иметь дело с возможными проблемами асинхронности; Вы можете позволить Vuex позаботиться о синхронизации состояний для вас и перестать беспокоиться о том, что данные null или undefined.

Магазин

export default {
  state: {
    userInfo: null
  },
  mutations: {
    UPDATE_USER(state, payload) {
      state.userInfo = payload;
    }
  }
}

Родитель / Приложение. js

export default {
  created() {
    // On firebase success callback
    this.$store.commit('UPDATE_USER', doc.data());
  }
}

Дети

import { mapState } from 'vuex';

export default {
  computed: {
    ...mapState([
      'userInfo'
    ])
  },

  created() { },
  mounted() { },
  methods() { 
    if (this.userInfo) {
      // Do something safely
    }
  },
  // Anywhere
}
0 голосов
/ 22 января 2020

Реквизит должен быть доступен в крючке created. Предполагая, что значения являются синхронными. Попробуйте добавить default значения, чтобы удалить ненужные v-if директивы. Это должно решить проблему как для синхронных, так и для асинхронных данных.

{
  props: {
    length: {
      type: Number,
      default: 0,
    },
  },
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...