Как заставить рендеринг одного компонента Vue от другого - PullRequest
0 голосов
/ 09 февраля 2019

У меня есть корзина покупок, в которой, когда я выбираю «добавить в корзину» в одном приложении, я хочу, чтобы корзина обновилась.При добавлении в корзину я размещаю этот пункт на API.Выборка корзины из этого API и отображает данные в компоненте корзины.

Я использую EventBus, чтобы сообщить компоненту корзины, что новый элемент был добавлен, однако в моей функции $on нет ни $forceUpdate(), ни выполнение другого запроса на выборку повторно отображает компонент с новым элементом.

Это в моем компоненте товара:

methods: {
submit(e){
  e.preventDefault()
  let data = this.createBasketObject(this.experience)
  fetch('http://localhost:3000/api/basket', {
    method: 'POST',
    body: JSON.stringify(data),
    headers: { 'Content-Type': 'application/json'}
  })
  .then( eventBus.$emit('basket-updated', true))
}

и это в моем компоненте корзины:

<template lang="html">
  <div class="">
    <h3>Basket</h3>
    <basket-item
      v-for="item in items"
      :key="item._id"
      :item="item"
    />
    <p>Total: £{{ total}}</p>
  </div>

<script>
import BasketItem from './BasketItem.vue';
import { eventBus } from '../main.js';

export default {
  name: 'basket',
  data(){
    return {
      items: [],
      total: 0
    }
  },
  components: {
    'basket-item': BasketItem
  },
  mounted(){
    fetch('http://localhost:3000/api/basket')
    .then(res => res.json())
    .then(data => this.items = data)
    .then(items => this.calcTotal(items))

    eventBus.$on('basket-updated', (data) => {
      if(data){
        this.$forceUpdate()
      }
    })
  }

Япо сути, пытается сделать setState, как в React, но корзина не обновляется до тех пор, пока я не обновлю страницу.

В любом случае я могу сделать это в Vue, не используя что-то вроде сокетов?

Спасибо

1 Ответ

0 голосов
/ 09 февраля 2019

Я думаю, что вам нужно ЗАГРУЗИТЬ элементы корзины на добавленном новом элементе, ЕСЛИ вам требуется «круговая поездка с сервером (отправка нового элемента на сервер, некоторые вызовы, обратно во внешний интерфейс с обновленной корзиной)»,Итак: поместите в отдельный метод загрузку корзины, вызовите ее из смонтированного и снова в событии обновления корзины: это самый короткий ответ:

LoadBasket() {
 fetch('http://localhost:3000/api/basket')
    .then(res => res.json())
    .then(data => this.items = data)
    .then(items => this.calcTotal(items));
}

mounted(){
  //The first time:
  this.LoadBasket();

  eventBus.$on('basket-updated', (data) => {
      if(data){
         //on basket updated
          this.LoadBasket();
      }
    });
}

Помните, что данные являются «реактивными» свойствами: если он изменится, то также будет обновлена ​​презентация (при необходимости, tnx для виртуального домена, используемого в VueJS): нет необходимости вызывать метод «обновить пользовательский интерфейс».

Кстати, если вынужно только добавить только что созданный элемент в список «Предметы», который вам нужен, только чтобы поместить его в массив:

this.Items.push(newItem);

PS: я рекомендую вам взглянуть на Vuex (https://vuex.vuejs.org/guide/state.html) дляуправление состоянием вашего приложения: оно немного сложнее, но позволяет улучшить дизайн вашего приложения.

...