Как передать данные в корзину в виде массива?
Товары удобно держать в "словаре": ключ id, значение объект товара.
Корзину – как тоже "словарь": ключ id товара, значение – количество в корзине.
Количество товара стало 0 или меньше – удаляем ключ из Корзины.
Так всё становится довольно однозначно.

Отрендерить товары – нужна одна функция делающая для 1 товара из данных – HTML.
То же для товаров в корзине.

Нажали плюс-минус: меняется количество в Корзине, и её всю целиком заново рендерим.

Общий принцип: данные → отрисовка по ним UI → действия пользователя меняют данные (и далее по кругу).
snippet
data-атрибуты, наверное, лишние, раз и так вешаем прямо обработчик клика – в него же сразу и id товара пропишем.
Приветствую!

1) любые не примитивные переменные лучше создавать через const,
2) data атрибуты - хорошее решение для связывания каких-либо HTML элементов с их логикой JS,
3) у Вас в коде идентификатор товара data[key].Id равняется идентификатору кнопки. А что, если у Вас на странице будет несколько категорий товаров? В категории А есть id == 1, в категории Б тоже есть товар с id == 1. При этом у каждого товара из каждой категории идентичные кнопки. Все сломается.

Теперь насчёт реализации.

Я бы предложил сделать каждую карточку товара блоком с data атрибутом, который полностью идентифицирует этот блок, как карточку непосредственного товара. Предположим, cakes-1 (категория товара-идентификатор товара), конкретный вариант идентификации зависит от требований. Более того, такую логику следует выполнять на уровне всего проекта или, хотя бы, конкретного модуля проекта. Тогда можно избавиться от ненужных идентификаций кнопок «+» и «-». Оставить на них только data атрибуты «plus / minus». При клике смотреть на карточку товара (она, как вы помните, один из предков родителя в DOM дереве) и брать из этой карточки data атрибут, идентифицирующий её. Расшифровывая данный атрибут можно уже идти в объект с данными и доставать оттуда необходимый Вам объект.

Про модель. При обработке клика на + или - Вы должны пушить / попить (доставать) в/из массив(а) товары. После каждого пуша / попа Вы можете пересчитывать количество товаров в массиве и выводить это количество на экран (обновлять счётчик) ИЛИ увеличивать / уменьшать заранее созданную переменную (например, count). Второе решение быстрее, но в некоторых задачах может стать неподходящим за счёт своей «отвлеченности» от реальных данных (от вашего реального массива корзины).

На самом деле, реализация может быть (и будет) куда сложнее, потому что здравомыслящий человек с конкретными задачами в проекте будет пытаться свести всю разработку и поддержание кода к максимально декларативному стилю. То есть, например, я хочу добавить новый элемент в массив кнопок навигации и получить новую кнопку на странице во все местах, где она используется за 10 секунд, а не описывать ее HTML код в разных частях проекта. Для этого, у вас все отрисовки должны происходить на основе данных, а не на основе реализаций. То есть, если Вы захотите добавить новую кнопку список кнопок и для этого Вам достаточно будет описать ее в структуре данных для кнопок на уровне JS в соответствии с интерфейсом кнопки, значит все круто! Если же Вам приходится для добавления нового раздела описывать HTML код в пяти местах проекта, значит Ваша система будет, явно, стоить очень дорого / долго :)

Для скорости и гибкости используются фреймворки. И тут есть даже такая шутка: «если в проекте не используется фреймворк, разработчики пишут свой».

Успехов Вам!