Добавление объекта item в массив из vue composition API

#javascript #vuejs2 #vue-composition-api

#javascript #vuejs2 #vue-composition-api

Вопрос:

Я пытаюсь добавить элементы, переданные из реквизитов, в ref свойство, используя vue-composition API . Но я не знаю, почему элементы не добавляются в массив. Возможно, я неправильно использую оператор spread или моя реализация неверна, но элемент не добавлен.

vue-composition метод находится в другом файле и используется во всем компоненте.

Я передаю реквизиты компоненту продукта таким образом:

  <product
    :id="12345667"
    title="Pampers 9x Sensitive Baby Wet Wipes Filler, 576 Diaper Wipes"
    price="14.59"
    :rating="4"
    image="https://images-na.ssl-images-amazon.com/images/I/41Yo4bc2uiL._AC_US160_.jpg"
  >
  </product>
  

Аналогично, компонент product является setup таким:

    <template>

    <div class="product">
          <button type="button" @click="addToCart(item)">Add to Basket</button>
    </div>

   </template>

   <script>
    import { useCart } from "../js/ShoppingCart";
    
    export default {
      setup(props) {
        let item = props;
    
        const { addToCart } = useCart();
    
        return { item, addToCart };
      },
      props: {
        id: Number,
        title: String,
        image: String,
        price: String,
        rating: Number,
      }
    };
    </script>
  

ShoppingCart.js где я использую @vue-composition-api

 import { ref } from "@vue/composition-api";
export function useCart() {
  let basket = ref([]);
  const addToCart = async (item) => {
    // eslint-disable-next-line no-debugger
    debugger;
    return {
      ...basket,
      item,
    };
  };
  console.log(JSON.stringify(basket));
  return { basket, addToCart };
}
  

Я не знаю, где я ошибся, basket массив всегда пуст при вызове из разных компонентов.

Обновленный вопрос:

 <template>
  <div class="home">
    <img
      class="home__image"
      src="https://images-na.ssl-images-amazon.com/images/G/01/AmazonExports/Fuji/2020/May/Hero/Fuji_TallHero_45M_es_US_2x._CB432534552_.jpg"
    />

    <div class="home__row">
      <product
        :id="12345667"
        title="Pampers 9x Sensitive Baby Wet Wipes Filler, 576 Diaper Wipes"
        price="14.59"
        :rating="4"
        image="https://images-na.ssl-images-amazon.com/images/I/41Yo4bc2uiL._AC_US160_.jpg"
      >
      </product>
      <product
        :id="12345667"
        title="Pampers 9x Sensitive Baby Wet Wipes Filler, 576 Diaper Wipes"
        price="14.59"
        :rating="4"
        image="https://images-na.ssl-images-amazon.com/images/I/41Yo4bc2uiL._AC_US160_.jpg"
      >
      </product>
      {{ basket }}
      basket length {{ basket.value ? basket.value.length : 0 }}
    </div>
  </div>
</template>
<script>
// @ is an alias to /src
import Product from "@/components/Product.vue";
import { useCart } from "../js/ShoppingCart";
export default {
  setup() {
    const { basket } = useCart();
    return { basket };
  },

  name: "Home",
  components: {
    Product,
  },
};
</script>
  

Ответ №1:

Я не вижу там ни одного места, где вы на самом деле обновляете basket массив.

Кроме того, вы не фиксируете возвращаемое значение, поэтому вы можете удалить его, и вам может не понадобиться async функция

Вы должны уметь использовать basket.value.push(item);

ShoppingCart.js

 import { ref } from "@vue/composition-api";
export function useCart() {
  let basket = ref([]);
  const addToCart = (item) => {
    basket.value.push(item);
  };
  return { basket, addToCart };
}
  

или basket.push(item); если вы переключитесь ref на reactive

ShoppingCart.js

 import { reactive } from "@vue/composition-api";
export function useCart() {
  let basket = reactive([]);
  const addToCart = (item) => {
    basket.push(item);
  };
  return { basket, addToCart };
}
  

Обновление # 1:

в вашем шаблоне, который вы используете {{ basket.value ? basket.value.length : 0 }}

Одна из проблем заключается в том, что value это решается с помощью шаблона, поэтому вы не должны использовать его в шаблоне.


Обновление # 2:

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

если вы запустите его таким образом, он создаст новый экземпляр:

 import { ref } from "@vue/composition-api";
export function useCart() {
  let basket = ref([]); // <--- new store, local to function
  const addToCart = (item) => {
    basket.value.push(item);
  };
  return { basket, addToCart };
}
  

но если вы обновите его до этого

 import { ref } from "@vue/composition-api";
let basket = ref([]); // <--- same store, global
export function useCart() {
  const addToCart = (item) => {
    basket.value.push(item);
  };
  return { basket, addToCart };
}
  

useCart() теперь будет повторно использоваться та же ссылка

Обновление # 3:

Не тестировал, но вы также можете попробовать это, чтобы обойти ошибку в Vue2

 import { ref, isRef } from "@vue/composition-api";
let basket;
export function useCart() {
  if (! isRef(basket)) basket = ref([]);
  const addToCart = (item) => {
    basket.value.push(item);
  };
  return { basket, addToCart };
}
  

Комментарии:

1. разве return { ...basket, item, }; отправка и возврат basket массива не выполняется?

2. он просто возвращает объект со сплющенной корзиной, за которым следует элемент

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

4. я использую basket length {{ basket.value ? basket.value.length : 0 }} для отображения длины массива. но количество всегда равно 0. Что может быть не так?

5. в шаблоне, который вам не нужен value . ` {{ корзина.значение ? корзина.ценность. длина : 0 }}` всегда будет возвращаться 0 , потому что basket.value не определено (ложно)