#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
не определено (ложно)