У меня есть список товаров в корзине, представленный в строках и столбцах Bootstrap. Каждый товар имеет входной номер PrimeVue для изменения количества конкретного товара в корзине.
Вот проект StackBlitz с этой проблемой.
Вот как я использую InputNumber:
<InputNumber v-model = "item.qty"
inputId = "horizontal-buttons"
showButtons
buttonLayout = "horizontal"
:step = "1"
style = "max-width: 100%; box-sizing: border-box;">
<template #incrementbuttonicon>
<span class = "material-symbols-sharp">
add
</span>
</template>
<template #decrementbuttonicon>
<span class = "material-symbols-sharp">
remove
</span>
</template>
</InputNumber>
Вот компонент со списком, который я упомянул выше:
<script setup>
import InputNumber from 'primevue/inputnumber'
import { useCartStore } from '../stores/cartStore.js'
import { storeToRefs } from 'pinia'
const cartStore = useCartStore()
const { cart } = storeToRefs(cartStore)
const { deleteFromCart } = cartStore
</script>
<template>
<div class = "row mw-2000 mx-auto px-lg-5 px-0 my-0">
<section class = "col-9">
<div class = "container-fluid">
<div class = "row border-top border-bottom cart-item"
v-for = "item in cart">
<img class = "col-2" :src = "item.product.images[0]" alt = "Product">
<div class = "col-6 d-inline-block overflow-ellipsis">
{{ item.product.title }}
</div>
<div class = "col-1 d-inline-block overflow-ellipsis">
${{ parseFloat(item.product.price).toFixed(2) }}
</div>
<div class = "col-2">
<InputNumber v-model = "item.qty"
inputId = "horizontal-buttons"
showButtons
buttonLayout = "horizontal"
:step = "1" style = "max-width: 100%; box-sizing: border-box;">
<template #incrementbuttonicon>
<span class = "material-symbols-sharp">
add
</span>
</template>
<template #decrementbuttonicon>
<span class = "material-symbols-sharp">
remove
</span>
</template>
</InputNumber>
</div>
<div class = "col-1 d-flex justify-content-end">
<button type = "button"
class = "btn btn-danger delete-product-btn d-inline-flex
justify-content-center align-items-center"
@click = "deleteFromCart(item.product.id)">
<span class = "material-symbols-sharp">
close
</span>
</button>
</div>
</div>
</div>
</section>
<section class = "col-3"></section>
</div>
</template>
Как видите, я попробовал применить style = "max-width: 100%; box-sizing: border-box;"
к компоненту InputNumber, но это не сработало. Я также попробовал заменить max-width: 100%
на width: 100%
, но это тоже не сработало. Прямо сейчас ввод выглядит так:
Я попытался проверить компонент, но не смог найти причину, по которой он ведет себя таким образом. Я нигде не видел, чтобы для InputNumber устанавливалась фиксированная ширина или что-то подобное.
Чтобы внести ясность: я хочу, чтобы InputNumber соответствовал ширине своего родителя.
Заранее спасибо!
@kissu, я изменил ссылку. Если появится ошибка, не стесняйтесь сообщить мне. А вот код страницы корзины на GitHub. И я осмотрел компонент. Не смог найти ни одной причины, почему он так себя ведет. Я нигде не видел, чтобы для InputNumber устанавливалась фиксированная ширина или что-то подобное.
Предоставленная вами песочница не работает. Без работающего вам вряд ли помогут с CSS. Нам нужен способ проверить результирующий HTML-результат вашего кода. Беглым взглядом я заметил, что вы путаете bootstrap
с primevue
. Это не очень хорошая идея, если только вы действительно не знаете, что делаете, и не отбираете элементы каждого из них, которые не конфликтуют.
Извините, вопрос закрыт. Прошу прощения за бесполезность.
Хм ? Что ты имеешь в виду?
@kissu, я имею в виду, что мне не следовало спрашивать об этом. Мне также не следовало использовать Bootstrap и PrimeVue вместе. Собираюсь это исправить. Спасибо, что обратили внимание! Пока!
Хорошо, эта платформа предназначена для того, чтобы задавать технические вопросы, чтобы вы могли совершенствоваться. Не бейте себя или что-то в этом роде. Это правда, что вам следует вообще отказаться от использования Bootstrap с Vue3, но если вы это сделаете, это не конец света, просто двигайтесь вперед. Вы проделали большую работу, правильно объяснив свою проблему + приложили к этому некоторые усилия, мне это показалось очень приятным для нового участника. :)
@kissu, спасибо за оценку моих стараний! Я действительно подумывал об удалении своей учетной записи, чтобы «больше не спрашивать что-то бесполезное». У меня никогда не было хороших отношений со StackOverflow.
@kissu, твои комментарии открыли мне глаза на фундаментальную проблему моего проекта. Я сделал неправильную вещь, используя PrimeVue и Bootstrap вместе. Но мне трудно принять решение о выборе одного из них. Мне очень нравятся компоненты PrimeVue. С их помощью мне удалось без особых усилий сделать многодиапазонный ценовой слайдер, который работает безупречно. Я также использую карусель из этого набора. Но у меня есть макет Bootstrap, и изменить его на PrimeFlex выглядит большой задачей, учитывая тот факт, что я еще не знаком с PrimeFlex. Думаю, я буду использовать Bootstrap.
@tao, я решил, что буду придерживаться Bootstrap. К сожалению, я не могу заставить песочницу работать. Когда я вхожу в систему и начинаю работать над ним, он запускается нормально. Но когда я использую общедоступную ссылку, я получаю эту ошибку @vnode-...
. Я пробовал удалить node_modules
, package-lock.json
и запустить npm install
, прежде чем поделиться, но это не помогло. Другого способа решения этой проблемы, к сожалению, я не нашел. Этот вопрос можете проигнорировать, оказалось, что у меня проблема с выбором стека технологий.
Было бы любопытно узнать, почему у SO нет хороших отношений, сейчас пишу об этом статью. Если вы используете Bootstrap только для макета, я рекомендую отказаться от него и использовать Flexbox или Grid, вам будет легче и вы получите хорошие основы в CSS. Вы могли бы даже попытаться отказаться от PrimeVue, если хотите полностью улучшить и изучить внутренности каждого используемого вами компонента. Если вам сложно создать минимально воспроизводимый пример, вы всегда можете поделиться общедоступным репозиторием ссылок на Github.
Давайте продолжим обсуждение в чате.
Хотя вы не смогли предоставить работоспособный пример (что практически обязательно для вопросов по CSS), ваш вопрос не был бесполезным (например, я заметил, что вы используете bootstrap
с primevue
). Если вам все еще нужен ответ на вопрос, рассмотрите возможность предоставления более простого минимально воспроизводимого примера (только рендеринг NumberInput
в контейнере), и мы сможем сказать вам, почему он не расширяется/сжимается, чтобы оправдать ожидания.
@tao, могу ли я разместить это на страницах GitHub? Этого будет достаточно? Чтобы было понятнее, я решил больше не использовать Bootstrap и заменить его Tailwind. Но мне, возможно, нужно знать, почему входные данные могут вести себя таким образом.
Я рекомендую разместить его на Netlify, страницы на Github не так уж и хороши, если честно.
@tao, я развернул проект на Netlify. Вот оно. Сначала добавьте в корзину несколько товаров.
Предоставленная вами ссылка не работает (поскольку вы не настроили должным образом маршрутизацию в Netlify, но это отдельная проблема, не имеющая здесь значения). Мне удалось получить доступ к приложению, удалив /products
из ссылки. Как мне попасть на страницу, которую вы указали в вопросе? Через меню приложения я его не нашел.
@tao, выберите категорию и подкатегорию продукта в раскрывающемся списке «Товар» на панели навигации. Вот так.Вы можете выбрать любой пункт из меню, все они ведут на одну страницу.
@tao, приношу глубокие извинения за неудобства, я новичок в Netlify.
Не нужно извинений. Для меня последовательность из 8 кликов, которую вы выполняете в демо-версии, не очевидна из ссылки, которую вы представили выше. Я бы, наверное, понял, как туда попасть, если бы ссылка заканчивалась на /cart
.
@tao, как я вижу, ты добрался, да? Моя вина, я не записал адресную строку. Простите за это.
Похоже, проблема решена применением 1, 2:
.p-inputnumber input {
width: 100%;
}
но я не уверен, что понимаю механику DOM, лежащую в основе этого.
Я предполагаю, что ширина автоматически устанавливается пользовательским агентом (браузером), который, согласно стандарту HTML, «должен гарантировать видимость не менее 20 символов». Это подтверждается сокращением входных данных при присвоении атрибуту size
значения меньше 20
(значение по умолчанию).
Я проверил весь CSS, примененный к span.p-inputnumber
, его внутреннему input
, его внутренним button
и внутренней тени input
, и ничто другое не объясняет, почему они превышают родительскую ширину.
Кроме того, похоже, что такое поведение не вызвано конфликтом правил CSS между primevue
и bootstrap
. (Я не говорю, что их совместное использование желательно, но я серьезно сомневаюсь, что это основная причина нежелательного поведения CSS).
1 — если вы хотите, чтобы такое поведение наблюдалось только на некоторых входных данных, примените исправление выборочно, используя специальный класс.
2 - присвоение входным значениям CSS overflow
auto
, hidden
, overlay
или scroll
, похоже, имеет тот же эффект, что и предлагаемое исправление (проверено только в Chrome).
3 - На вашем месте я бы открыл проблему в репозитории primevue сообщил им о поведении, вероятно, они хотят это исправить. Большинство разработчиков ожидают, что вводимые данные не будут превышать ширину родительского элемента без необходимости применения какого-либо CSS.
Спасибо! Не знаю, почему я забыл об атрибуте size
и его значении по умолчанию. Все ваши исправления работают как часы. Мне бы хотелось дать вашему ответу миллион голосов. Что касается PrimeVue, я открою вопрос в его репозитории на GitHub.
Коды и ящик не являются общедоступными. В противном случае я рекомендую проверить весь элемент HTML в инструментах разработчика вашего браузера, чтобы понять, почему он ведет себя не так, как вы ожидаете.